package service

import (
	"encoding/json"
	"errors"
	"fmt"
	"math"
	"qld2devservice/models"
	"qld2devservice/utils"
	"strconv"
	"strings"
	"time"
)

func AnalyzePowerMessageType0(snNum, message string) {
	if isWorking, err := RedisGet(snNum+"/isWorking", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "checkState:1，etcd数据isWorking获取失败"))
	} else if isWorking == "1" {
		var mapResult map[string]string
		err := json.Unmarshal([]byte(message), &mapResult)
		if err != nil {
			utils.MyPrint(utils.PRINT_ERROR, err.Error())
		} else {
			if len(mapResult["power"]) == 20 {
				var power int
				var electricity int
				var voltage int
				var current int
				powerStr := []byte(mapResult["power"])
				power = int(powerStr[0] - '0')
				power <<= 4
				power |= int(powerStr[1] - '0')
				power <<= 4
				power |= int(powerStr[2] - '0')
				power <<= 4
				power |= int(powerStr[3] - '0')

				electricity = int(powerStr[4] - '0')
				electricity <<= 4
				electricity |= int(powerStr[5] - '0')
				electricity <<= 4
				electricity |= int(powerStr[6] - '0')
				electricity <<= 4
				electricity |= int(powerStr[7] - '0')
				electricity <<= 4
				electricity |= int(powerStr[8] - '0')
				electricity <<= 4
				electricity |= int(powerStr[9] - '0')
				electricity <<= 4
				electricity |= int(powerStr[10] - '0')
				electricity <<= 4
				electricity |= int(powerStr[11] - '0')

				voltage = int(powerStr[12] - '0')
				voltage <<= 4
				voltage |= int(powerStr[13] - '0')
				voltage <<= 4
				voltage |= int(powerStr[14] - '0')
				voltage <<= 4
				voltage |= int(powerStr[15] - '0')

				current = int(powerStr[16] - '0')
				current <<= 4
				current |= int(powerStr[17] - '0')
				current <<= 4
				current |= int(powerStr[18] - '0')
				current <<= 4
				current |= int(powerStr[19] - '0')

				electricityKWH := float64(electricity/3600) / 1000
				electricityKWH = processElectricity(electricityKWH)

				if electricity == 0 {
					utils.MyPrint(utils.PRINT_WARN, "电量为0，使用之前的旧值")
					if electricityLastStr, err := RedisGet(snNum+"/electricity", "0"); err != nil {
						utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzePowerMessageType0,1:etcd服务电费数据获取失败"))
					} else if electricityLast, err := strconv.ParseFloat(electricityLastStr, 64); err != nil {
						utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzePowerMessageType0,1:etcd服务电费数据获取失败"))
					} else {
						electricityKWH = electricityLast
					}
				}

				duration, err := AnalyzeDevDurationGet(snNum + "/openTime")
				if err != nil {
					utils.MyPrint(utils.PRINT_ERROR, err.Error())
				}
				amountFen, err := calculateAmount(snNum, electricityKWH, duration, 0)
				if err != nil {
					utils.MyPrint(utils.PRINT_ERROR, err.Error())
				}
				powerKW := float64(power) / 1000
				voltageV := float64(voltage) / 100
				currentA := float64(current) / 1000

				if err = RedisSave(snNum+"/electricity", strconv.FormatFloat(electricityKWH, 'E', -1, 64)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, err.Error())
				}
				if err = MqttNoticeSend(snNum+"/electricity", strconv.FormatFloat(electricityKWH, 'E', -1, 64)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
				}
				if err = RedisSave(snNum+"/power", strconv.FormatFloat(powerKW, 'E', -1, 64)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, err.Error())
				}
				if err = MqttNoticeSend(snNum+"/power", strconv.FormatFloat(powerKW, 'E', -1, 64)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
				}
				if err = RedisSave(snNum+"/voltage", strconv.FormatFloat(voltageV, 'E', -1, 64)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, err.Error())
				}
				if err = MqttNoticeSend(snNum+"/voltage", strconv.FormatFloat(voltageV, 'E', -1, 64)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
				}
				if err = RedisSave(snNum+"/current", strconv.FormatFloat(currentA, 'E', -1, 64)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, err.Error())
				}
				if err = MqttNoticeSend(snNum+"/current", strconv.FormatFloat(currentA, 'E', -1, 64)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
				}

				amountLastStr, err := RedisGet(snNum+"/amount", "0")
				if err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
				}
				amountLast, err := strconv.ParseInt(amountLastStr, 10, 64)
				if err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,2:etcd服务电费数据转换失败"))
				}
				amountRecordLast, err := RedisGet(snNum+"/amountRecord", "")
				if err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
				}
				if err = RedisSave(snNum+"/amount", strconv.FormatInt(amountFen, 10)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, err.Error())
				}
				if err = MqttNoticeSend(snNum+"/amount", strconv.FormatInt(amountFen, 10)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
				}
				amountRecord, err := CalculateAmountRecord(snNum)
				if err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "OutLetClose关闭设备:10，活动订单sn失败"))
					return
				}
				if err = RedisSave(snNum+"/amountRecord", amountRecord); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, err.Error())
				}
				remainAmount, err := calculateRemainAmount(snNum) // 必须在amount保存的后面
				if err = RedisSave(snNum+"/remainAmount", strconv.FormatInt(remainAmount, 10)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, err.Error())
				}
				if err = MqttNoticeSend(snNum+"/remainAmount", strconv.FormatInt(remainAmount, 10)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
				}

				// 设置金额用完，自动结算
				if openAmountStr, err := RedisGet(snNum+"/openAmount", "0"); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzePowerMessageType0,5:RedisGet充满停止，num="+snNum))
				} else if openAmount, err := strconv.ParseInt(openAmountStr, 10, 64); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "OutLetClose关闭设备:10，活动订单sn失败"))
				} else {
					if openAmount > 0 && amountFen > openAmount {
						utils.MyPrint(utils.PRINT_WARN, "******************关闭设备******************")
						if timeout, operateFlag, err := OperateDevice(snNum, OperateDeviceCloseIOValue, 0, 2, 15); err != nil {
							utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
						} else if timeout {
							utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "SaveOpenTime,1:etcd服务数据保存失败"))
						} else if operateFlag != 0 {
							utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "SaveOpenTime,1:etcd服务数据保存失败"))
						} else {
							//1充满停止、2金额用完停止、3闲置停止、4汽车未允许充电停止、5拔出停止、6功率超限停止、7电量超限停止、8时间超限停止
							powerFinishOrder(snNum, 2, amountLast, duration, electricityKWH, amountRecordLast)
							return
						}
					}
				}
				// 余额不足，自动结算
				if remainAmount < 0 {
					utils.MyPrint(utils.PRINT_WARN, "******************关闭设备******************")
					if timeout, operateFlag, err := OperateDevice(snNum, OperateDeviceCloseIOValue, 0, 2, 15); err != nil {
						utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
					} else if timeout {
						utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "SaveOpenTime,1:etcd服务数据保存失败"))
					} else if operateFlag != 0 {
						utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "SaveOpenTime,1:etcd服务数据保存失败"))
					} else {
						//1充满停止、2金额用完停止、3闲置停止、4汽车未允许充电停止、5拔出停止、6功率超限停止、7电量超限停止、8时间超限停止
						powerFinishOrder(snNum, 2, amountLast, duration, electricityKWH, amountRecordLast)
						return
					}
				}

				// 保存上一次推送时间，以判断充电时间是否到达某一时刻，用于分时段计费
				if err = RedisSave(snNum+"/powerUpdateTime", time.Now().Format("2006-01-02 15:04:05")); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
				}

				var qldOutletControlJson models.QldOutletControlJson
				if qldOutletControlJsonStr, err1 := RedisGet(snNum+"/control", "{}"); err1 != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err1, "calculateAmount:3，获取设备etcd价格失败"))
				} else if err := json.Unmarshal([]byte(qldOutletControlJsonStr), &qldOutletControlJson); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err1, "calculateAmount:3，获取设备etcd价格失败"))
				} else {
					//若功率未达到充满标准，更新时间
					if powerKW > qldOutletControlJson.ChargeFullLowPower {
						if err = RedisSave(snNum+"/powerPowerStartLowTime", time.Now().Format("2006-01-02 15:04:05")); err != nil {
							utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
						}
						utils.MyPrint(utils.PRINT_WARN, powerKW, ">", qldOutletControlJson.ChargeFullLowPower)
					} else {
						utils.MyPrint(utils.PRINT_WARN, powerKW, "<=", qldOutletControlJson.ChargeFullLowPower)
					}
					// 读取开始充满低功率的时长，以根据功率判断是否充满电
					powerPowerStartLowTimeDuration, err := AnalyzeDevDurationGet(snNum + "/powerPowerStartLowTime")
					if err != nil {
						utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerDurationGet,2:etcd服务设备打开时间数据转换失败"))
					}
					// 充满低功率持续指定时间，认为充满
					if powerPowerStartLowTimeDuration > qldOutletControlJson.ChargeFullKeepDuration {
						if err = RedisSave(snNum+"/powerPowerStartLowTime", time.Now().Format("2006-01-02 15:04:05")); err != nil {
							utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
						} else {
							utils.MyPrint(utils.PRINT_WARN, "******************关闭设备******************")
							if timeout, operateFlag, err := OperateDevice(snNum, OperateDeviceCloseIOValue, 0, qldOutletControlJson.OperateNum, qldOutletControlJson.OperateWaitDuration); err != nil {
								utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzePowerMessageType0,1:OperateDevice操作设备失败，num="+snNum))
							} else if timeout {
								utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "AnalyzePowerMessageType0,2:OperateDevice操作设备超时，num="+snNum))
							} else if operateFlag != 0 {
								utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "AnalyzePowerMessageType0,3:OperateDevice操作设备失败，num="+snNum))
							} else {
								utils.MyPrint(utils.PRINT_WARN, "AnalyzePowerMessageType0,4:OperateDevice充满停止，num="+snNum)
								//1充满停止、2金额用完停止、3闲置停止、4汽车未允许充电停止、5拔出停止、6功率超限停止、7电量超限停止、8时间超限停止
								powerFinishOrder(snNum, 1, amountFen, duration, electricityKWH, amountRecord)
								return
							}
						}
					}

					// 功率超限，自动结算
					if qldOutletControlJson.MaxPower > 0 && powerKW > qldOutletControlJson.MaxPower {
						utils.MyPrint(utils.PRINT_WARN, "******************关闭设备******************")
						if timeout, operateFlag, err := OperateDevice(snNum, OperateDeviceCloseIOValue, 0, 2, 15); err != nil {
							utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
						} else if timeout {
							utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "SaveOpenTime,1:etcd服务数据保存失败"))
						} else if operateFlag != 0 {
							utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "SaveOpenTime,1:etcd服务数据保存失败"))
						} else {
							//1充满停止、2金额用完停止、3闲置停止、4汽车未允许充电停止、5拔出停止、6功率超限停止、7电量超限停止、8时间超限停止
							powerFinishOrder(snNum, 6, amountFen, duration, electricityKWH, amountRecord)
							return
						}
					}
					// 电量超限，自动结算
					if qldOutletControlJson.MaxElectricity > 0 && electricityKWH > qldOutletControlJson.MaxElectricity {
						utils.MyPrint(utils.PRINT_WARN, "******************关闭设备******************")
						if timeout, operateFlag, err := OperateDevice(snNum, OperateDeviceCloseIOValue, 0, 2, 15); err != nil {
							utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
						} else if timeout {
							utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "SaveOpenTime,1:etcd服务数据保存失败"))
						} else if operateFlag != 0 {
							utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "SaveOpenTime,1:etcd服务数据保存失败"))
						} else {
							//1充满停止、2金额用完停止、3闲置停止、4汽车未允许充电停止、5拔出停止、6功率超限停止、7电量超限停止、8时间超限停止
							powerFinishOrder(snNum, 7, amountFen, duration, electricityKWH, amountRecord)
							return
						}
					}
					// 时间超限，自动结算
					if qldOutletControlJson.MaxDuration > 0 && duration > qldOutletControlJson.MaxDuration {
						utils.MyPrint(utils.PRINT_WARN, "******************关闭设备******************")
						if timeout, operateFlag, err := OperateDevice(snNum, OperateDeviceCloseIOValue, 0, 2, 15); err != nil {
							utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
						} else if timeout {
							utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "SaveOpenTime,1:etcd服务数据保存失败"))
						} else if operateFlag != 0 {
							utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "SaveOpenTime,1:etcd服务数据保存失败"))
						} else {
							//1充满停止、2金额用完停止、3闲置停止、4汽车未允许充电停止、5拔出停止、6功率超限停止、7电量超限停止、8时间超限停止
							powerFinishOrder(snNum, 8, amountFen, duration, electricityKWH, amountRecord)
							return
						}
					}
				}
			}
		}
	}
}

func AnalyzePowerMessageType1(snNum, message string) {
	if isWorking, err := RedisGet(snNum+"/isWorking", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "checkState:1，etcd数据isWorking获取失败"))
	} else if isWorking == "1" {
		var mapResult map[string]string
		err := json.Unmarshal([]byte(message), &mapResult)
		if err != nil {
			utils.MyPrint(utils.PRINT_ERROR, err.Error())
		} else {
			if len(mapResult["power"]) == 20 {
				var power int
				var electricity int
				var voltage int
				var current int
				powerStr := []byte(mapResult["power"])
				power = int(powerStr[0] - '0')
				power <<= 4
				power |= int(powerStr[1] - '0')
				power <<= 4
				power |= int(powerStr[2] - '0')
				power <<= 4
				power |= int(powerStr[3] - '0')

				electricity = int(powerStr[4] - '0')
				electricity <<= 4
				electricity |= int(powerStr[5] - '0')
				electricity <<= 4
				electricity |= int(powerStr[6] - '0')
				electricity <<= 4
				electricity |= int(powerStr[7] - '0')
				electricity <<= 4
				electricity |= int(powerStr[8] - '0')
				electricity <<= 4
				electricity |= int(powerStr[9] - '0')
				electricity <<= 4
				electricity |= int(powerStr[10] - '0')
				electricity <<= 4
				electricity |= int(powerStr[11] - '0')

				voltage = int(powerStr[12] - '0')
				voltage <<= 4
				voltage |= int(powerStr[13] - '0')
				voltage <<= 4
				voltage |= int(powerStr[14] - '0')
				voltage <<= 4
				voltage |= int(powerStr[15] - '0')

				current = int(powerStr[16] - '0')
				current <<= 4
				current |= int(powerStr[17] - '0')
				current <<= 4
				current |= int(powerStr[18] - '0')
				current <<= 4
				current |= int(powerStr[19] - '0')

				electricityLastStr, err := RedisGet(snNum+"/electricity", "0")
				if err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
				}
				electricityLast, err := strconv.ParseFloat(electricityLastStr, 64)
				if err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
				}

				duration, err := AnalyzeDevDurationGet(snNum + "/openTime")
				if err != nil {
					utils.MyPrint(utils.PRINT_ERROR, err.Error())
				}
				electricityf := float64(electricity/3600) / 1000
				electricityf = processElectricity(electricityf)

				electricityKWH := getActualElectricity(snNum, electricityf, electricityLast, duration)

				openType, err := GetOpenType(snNum)
				if err != nil {
					utils.WrapError(err, "OutLetClose关闭设备:10，活动订单sn失败")
				}
				//amountFen, err := calculateAmount(snNum, electricityKWH, duration, openType)
				//if err != nil {
				//	utils.MyPrint(utils.PRINT_ERROR, err.Error())
				//}
				powerKW := float64(power) / 1000
				voltageV := float64(voltage) / 100
				currentA := float64(current) / 1000

				if err = RedisSave(snNum+"/electricity", strconv.FormatFloat(electricityKWH, 'E', -1, 64)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, err.Error())
				}
				if err = MqttNoticeSend(snNum+"/electricity", strconv.FormatFloat(electricityKWH, 'E', -1, 64)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
				}
				if err = RedisSave(snNum+"/power", strconv.FormatFloat(powerKW, 'E', -1, 64)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, err.Error())
				}
				if err = MqttNoticeSend(snNum+"/power", strconv.FormatFloat(powerKW, 'E', -1, 64)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
				}
				if err = RedisSave(snNum+"/voltage", strconv.FormatFloat(voltageV, 'E', -1, 64)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, err.Error())
				}
				if err = MqttNoticeSend(snNum+"/voltage", strconv.FormatFloat(voltageV, 'E', -1, 64)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
				}
				if err = RedisSave(snNum+"/current", strconv.FormatFloat(currentA, 'E', -1, 64)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, err.Error())
				}
				if err = MqttNoticeSend(snNum+"/current", strconv.FormatFloat(currentA, 'E', -1, 64)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
				}
				//将功率存储到redis的List中,只存储前10个_start
				err = SetPowerToRedis(powerKW*1000, snNum)
				if err != nil {
					fmt.Println("将功率存储到redis的List中失败了:", err)
				}
				//将功率存储到redis的List中,只存储前10个_end

				isWebsocketMonitor, err := RedisGetNoHeader("/qld2websocket/"+snNum, "0")

				var amountFen = int64(0)

				if err != nil {
					utils.MyPrint(utils.PRINT_ERROR, err)
				} else {
					if isWebsocketMonitor == "1" {
						if electricityKWH > 10 {
							utils.MyPrint(utils.PRINT_ERROR, snNum, "电量错误")
							electricityKWH = 0.5
						}

						amountFen2, err := calculateAmount(snNum, electricityKWH, duration, openType)
						if err != nil {
							utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzePowerMessageNew,3:功率数据转换失败"))
						}
						amountFen = amountFen2
						utils.MyPrint(utils.PRINT_WARN, electricityKWH, powerKW, voltageV, currentA, amountFen2)
						if err = MqttNoticeSend(snNum+"/amount", strconv.FormatInt(amountFen, 10)); err != nil {
							utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
						}
					}
				}

				//amountLastStr, err := RedisGet(snNum+"/amount", "0")
				//if err != nil {
				//	utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
				//}
				//amountLast, err := strconv.ParseInt(amountLastStr, 10, 64)
				//if err != nil {
				//	utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,2:etcd服务电费数据转换失败"))
				//}
				//amountRecordLast, err := RedisGet(snNum+"/amountRecord", "")
				//if err != nil {
				//	utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
				//}
				//if err = RedisSave(snNum+"/amount", strconv.FormatInt(amountFen, 10)); err != nil {
				//	utils.MyPrint(utils.PRINT_ERROR, err.Error())
				//}
				//if err = MqttNoticeSend(snNum+"/amount", strconv.FormatInt(amountFen, 10)); err != nil {
				//	utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
				//}
				//amountRecord, err := CalculateAmountRecord(snNum)
				//if err != nil {
				//	utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "OutLetClose关闭设备:10，活动订单sn失败"))
				//}
				//if err = RedisSave(snNum+"/amountRecord", amountRecord); err != nil {
				//	utils.MyPrint(utils.PRINT_ERROR, err.Error())
				//}
				//remainAmount, err := calculateRemainAmount(snNum) // 必须在amount保存的后面
				//if err = RedisSave(snNum+"/remainAmount", strconv.FormatInt(remainAmount, 10)); err != nil {
				//	utils.MyPrint(utils.PRINT_ERROR, err.Error())
				//}
				//if err = MqttNoticeSend(snNum+"/remainAmount", strconv.FormatInt(remainAmount, 10)); err != nil {
				//	utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
				//}

				// 读取上一次推送时间，以判断充电时间是否到达某一时刻，用于分时段计费
				//powerLastUpdateTime := timeNow
				//if powerLastUpdateTimeStr,err := RedisGet(snNum+"/powerUpdateTime"); err != nil {
				//	utils.MyPrint(utils.PRINT_ERROR , utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
				//}else if len(powerLastUpdateTimeStr)>0 {
				//	if powerLastUpdateTime, err = time.Parse("2006-01-02 15:04:05", powerLastUpdateTimeStr);err != nil {
				//		errNew := utils.WrapError(err, "AnalyzeDevPowerDurationGet,2:etcd服务设备打开时间数据转换失败")
				//		utils.MyPrint(utils.PRINT_ERROR , errNew.Msg())
				//	}
				//}
				// 保存上一次推送时间，以判断充电时间是否到达某一时刻，用于分时段计费
				if err = RedisSave(snNum+"/powerUpdateTime", time.Now().Format("2006-01-02 15:04:05")); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
				}

				// 设置金额用完，自动结算
				//if openAmountStr, err := RedisGet(snNum+"/openAmount", "0"); err != nil {
				//	utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "OutLetClose关闭设备:10，活动订单sn失败"))
				//} else if openAmount, err := strconv.ParseInt(openAmountStr, 10, 64); err != nil {
				//	utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "OutLetClose关闭设备:10，活动订单sn失败"))
				//} else {
				//	if openAmount > 0 && amountFen > openAmount {
				//		utils.MyPrint(utils.PRINT_WARN, "******************关闭设备******************")
				//		if timeout, operateFlag, err := OperateDevice(snNum, OperateDeviceCloseIOValue, 0, 2, 15); err != nil {
				//			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
				//		} else if timeout {
				//			utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "SaveOpenTime,1:etcd服务数据保存失败"))
				//		} else if operateFlag != 0 {
				//			utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "SaveOpenTime,1:etcd服务数据保存失败"))
				//		} else {
				//			//1充满停止、2金额用完停止、3闲置停止、4汽车未允许充电停止、5拔出停止、6功率超限停止、7电量超限停止、8时间超限停止
				//			powerFinishOrder(snNum, 2, amountLast, duration, electricityKWH, amountRecordLast)
				//			return
				//		}
				//	}
				//}
				//// 余额不足，自动结算
				//if remainAmount < 0 {
				//	utils.MyPrint(utils.PRINT_WARN, "******************关闭设备******************")
				//	if timeout, operateFlag, err := OperateDevice(snNum, OperateDeviceCloseIOValue, 0, 2, 15); err != nil {
				//		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
				//	} else if timeout {
				//		utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "SaveOpenTime,1:etcd服务数据保存失败"))
				//	} else if operateFlag != 0 {
				//		utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "SaveOpenTime,1:etcd服务数据保存失败"))
				//	} else {
				//		//1充满停止、2金额用完停止、3闲置停止、4汽车未允许充电停止、5拔出停止、6功率超限停止、7电量超限停止、8时间超限停止
				//		powerFinishOrder(snNum, 2, amountLast, duration, electricityKWH, amountRecordLast)
				//		return
				//	}
				//}
				//zhangsen modify 20210526   增加最大充电时长
				if timetype, err1 := RedisGet(snNum+"/timeType", "0"); err1 != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err1, "timetype:获取充满判断类型失败"))
				} else if timetype == "1" {
					if hournum, err2 := RedisGet(snNum+"/hourNum", "0"); err2 != nil {
						utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err1, "hournum:获取最大充满时长失败"))
					} else {
						hour, err3 := strconv.Atoi(hournum)
						if err3 != nil {
							utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err3, "hournum:转化为整形变量失败"))
						} else {
							if duration > int64(hour*3600) {
								if timeout, operateFlag, err := OperateDevice(snNum, OperateDeviceCloseIOValue, 0, 2, 15); err != nil {
									utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzePowerMessageType1,1:redis数据保存失败"))
								} else if timeout {
									utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "AnalyzePowerMessageType1,1:设备控制超时"))
								} else if operateFlag != 0 {
									utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "AnalyzePowerMessageType1,1:设备控制失败"))
								} else {

									amountFen, amountRecord, err := CalculateAmountType(snNum)
									if err != nil {
										utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "CalculateAmountType 失败"))
									}

									//1充满停止、2金额用完停止、3闲置停止、4汽车未允许充电停止、5拔出停止、6功率超限停止、7电量超限停止、8时间超限停止
									powerFinishOrder(snNum, 8, amountFen, duration, electricityKWH, amountRecord)
									return
								}
							}
						}
					}
				}

				var qldOutletControlJson models.QldOutletControlJson
				if qldOutletControlJsonStr, err1 := RedisGet(snNum+"/control", "{}"); err1 != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err1, "calculateAmount:3，获取设备etcd价格失败"))
				} else if err := json.Unmarshal([]byte(qldOutletControlJsonStr), &qldOutletControlJson); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err1, "calculateAmount:3，获取设备etcd价格失败"))
				} else {
					if electricityKWH > electricityLast && electricityKWH >= qldOutletControlJson.PushOverPriceModeElectricity && electricityLast < qldOutletControlJson.PushOverPriceModeElectricity {
						//fmt.Println(",,,,,,,,,,,,,,,,,,,,,,,,,,,,,", electricityKWH, electricityLast)
						if userIdStr, err7 := RedisGet(snNum+"/userId", "0"); err7 != nil {
							utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err7, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
						} else if userId, err8 := strconv.ParseInt(userIdStr, 10, 64); err8 != nil {
							utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err8, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
						} else {
							//fmt.Println(",,,,,,,,,,,,,,,,,,,,,,,,,,,,,")
							ElectriciyWeiXinMassage(userId, "电量超过"+strconv.FormatFloat(qldOutletControlJson.PushOverPriceModeElectricity, 'E', -1, 64)+"度电，将按电量计费。", "电量超限", snNum)
							ElectriciyWeiXinMassageGdt(userId, "电量超过"+strconv.FormatFloat(qldOutletControlJson.PushOverPriceModeElectricity, 'E', -1, 64)+"度电，将按电量计费。", "电量超限", snNum)
							ElectriciyAliMassageGdt(userId, "电量超过"+strconv.FormatFloat(qldOutletControlJson.PushOverPriceModeElectricity, 'E', -1, 64)+"度电，将按电量计费。", "电量超限", snNum)
						}
					} else {
						//	fmt.Println("]]]]]]]]]]]]]]]]]]]]]]]]]]]]]", electricityKWH, electricityLast)
					}

					if openType != 1 { // 小交流在打开模式为1的情况下不断电
						//若功率未达到充满标准，更新时间
						if powerKW > qldOutletControlJson.ChargeFullLowPower {
							if err = RedisSave(snNum+"/powerPowerStartLowTime", time.Now().Format("2006-01-02 15:04:05")); err != nil {
								utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
							}
							utils.MyPrint(utils.PRINT_WARN, powerKW, ">", qldOutletControlJson.ChargeFullLowPower)
						} else {
							utils.MyPrint(utils.PRINT_WARN, powerKW, "<=", qldOutletControlJson.ChargeFullLowPower)
						}
						// 读取开始充满低功率的时长，以根据功率判断是否充满电
						powerPowerStartLowTimeDuration, err := AnalyzeDevDurationGet(snNum + "/powerPowerStartLowTime")
						if err != nil {
							utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerDurationGet,2:etcd服务设备打开时间数据转换失败"))
						}
						// 充满低功率持续，认为充满
						if powerPowerStartLowTimeDuration > qldOutletControlJson.ChargeFullKeepDuration {
							if err = RedisSave(snNum+"/powerPowerStartLowTime", time.Now().Format("2006-01-02 15:04:05")); err != nil {
								utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
							} else {
								utils.MyPrint(utils.PRINT_WARN, "******************关闭设备******************")
								if timeout, operateFlag, err := OperateDevice(snNum, OperateDeviceCloseIOValue, 0, 2, 15); err != nil {
									utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzePowerMessageType1,1:etcd服务数据保存失败"))
								} else if timeout {
									utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "AnalyzePowerMessageType1,1:设备控制超时"))
								} else if operateFlag != 0 {
									utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "AnalyzePowerMessageType1,1:设备控制失败"))
								} else {
									if powerKW == 0 {
										amountFen, amountRecord, err := CalculateAmountType(snNum)
										if err != nil {
											utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "CalculateAmountType 失败"))
										}
										//1充满停止、2金额用完停止、3闲置停止、4汽车未允许充电停止、5拔出停止、6功率超限停止、7电量超限停止、8时间超限停止
										powerFinishOrder(snNum, 3, amountFen, duration, electricityKWH, amountRecord)
									} else {
										amountFen, amountRecord, err := CalculateAmountType(snNum)
										if err != nil {
											utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "CalculateAmountType 失败"))
										}
										powerFinishOrder(snNum, 1, amountFen, duration, electricityKWH, amountRecord)
									}
									return
								}
							}
						}
					} else { //opentype==1
						// 余额不足，每隔一段时间通知
						//小插座先不判断余额
						//if remainAmount < qldOutletControlJson.BalanceShort {
						//	if remainAmountShortNoticeTimeStr, err22 := RedisGet(snNum+"/remainAmountShortNoticeTime", ""); err22 != nil {
						//		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err22, "SaveOpenTime,1:etcd服务数据保存失败"))
						//	} else if len(remainAmountShortNoticeTimeStr) == 0 {
						//		//通知余额不足
						//		fmt.Println("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")
						//		if userIdStr, err23 := RedisGet(snNum+"/userId", "0"); err23 != nil {
						//			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err23, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
						//		} else if userId, err24 := strconv.ParseInt(userIdStr, 10, 64); err24 != nil {
						//			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err24, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
						//		} else {
						//			fmt.Println("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")
						//
						//			BalanceWeiXinMassage(userId, remainAmount, "余额不足"+strconv.FormatFloat(float64(qldOutletControlJson.BalanceShort)/100, 'E', -1, 64)+"元，请及时充值。")
						//		}
						//
						//		if err25 := RedisSave(snNum+"/remainAmountShortNoticeTime", time.Now().Format("2006-01-02 15:04:05")); err25 != nil {
						//			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err25, "SaveOpenTime,1:etcd服务数据保存失败"))
						//		}
						//	} else if remainAmountShortNoticeTime, err26 := time.Parse("2006-01-02 15:04:05", remainAmountShortNoticeTimeStr); err26 != nil {
						//		errNew := utils.WrapError(err26, "AnalyzeDevPowerDurationGet,2:etcd服务设备打开时间数据转换失败")
						//		utils.MyPrint(utils.PRINT_ERROR, errNew.Msg())
						//	} else if time.Now().Sub(remainAmountShortNoticeTime) > (time.Second * time.Duration(qldOutletControlJson.PushBalanceShortDuration)) {
						//		//通知余额不足20元
						//		fmt.Println("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")
						//		if userIdStr, err27 := RedisGet(snNum+"/userId", "0"); err27 != nil {
						//			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err27, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
						//		} else if userId, err28 := strconv.ParseInt(userIdStr, 10, 64); err28 != nil {
						//			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err28, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
						//		} else {
						//			fmt.Println("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\")
						//			BalanceWeiXinMassage(userId, remainAmount, "余额不足"+strconv.FormatFloat(float64(qldOutletControlJson.BalanceShort)/100, 'E', -1, 64)+"元，请及时充值。")
						//		}
						//
						//		if err29 := RedisSave(snNum+"/remainAmountShortNoticeTime", time.Now().Format("2006-01-02 15:04:05")); err29 != nil {
						//			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err29, "SaveOpenTime,1:etcd服务数据保存失败"))
						//		}
						//	}
						//}
					}
					// 功率超限，自动结算
					if qldOutletControlJson.MaxPower > 0 {
						if powerLastStr, err := RedisGet(snNum+"/powerLast", "0"); err != nil {
							utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
						} else if powerLast, err := strconv.ParseFloat(powerLastStr, 64); err != nil {
							utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
						} else if powerKW > qldOutletControlJson.MaxPower && powerLast > qldOutletControlJson.MaxPower {
							utils.MyPrint(utils.PRINT_WARN, "******************关闭设备******************")
							if timeout, _, err := OperateDevice(snNum, OperateDeviceCloseIOValue, 0, 2, 15); err != nil {
								utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
							} else if timeout {
								utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "SaveOpenTime,1:etcd服务数据保存失败"))
							} else {
								amountFen, amountRecord, err := CalculateAmountType(snNum)
								if err != nil {
									utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "CalculateAmountType 失败"))
								}
								//1充满停止、2金额用完停止、3闲置停止、4汽车未允许充电停止、5拔出停止、6功率超限停止、7电量超限停止、8时间超限停止
								powerFinishOrder(snNum, 6, amountFen, duration, electricityKWH, amountRecord)
								return
							}
						}
						if err = RedisSave(snNum+"/powerLast", strconv.FormatFloat(powerKW, 'E', -1, 64)); err != nil {
							utils.MyPrint(utils.PRINT_ERROR, err.Error())
						}
					}
					// 电量超限，自动结算
					if qldOutletControlJson.MaxElectricity > 0 && electricityKWH > qldOutletControlJson.MaxElectricity {
						utils.MyPrint(utils.PRINT_WARN, "******************关闭设备******************")
						if timeout, _, err := OperateDevice(snNum, OperateDeviceCloseIOValue, 0, 2, 15); err != nil {
							utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
						} else if timeout {
							utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "SaveOpenTime,1:etcd服务数据保存失败"))
						} else {
							amountFen, amountRecord, err := CalculateAmountType(snNum)
							if err != nil {
								utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "CalculateAmountType 失败"))
							}
							//1充满停止、2金额用完停止、3闲置停止、4汽车未允许充电停止、5拔出停止、6功率超限停止、7电量超限停止、8时间超限停止
							powerFinishOrder(snNum, 7, amountFen, duration, electricityKWH, amountRecord)
							return
						}
					}
					// 时间超限，自动结算
					if int64(qldOutletControlJson.MaxDuration) > 0 && duration > int64(qldOutletControlJson.MaxDuration) {
						utils.MyPrint(utils.PRINT_WARN, "******************关闭设备******************")
						if timeout, _, err := OperateDevice(snNum, OperateDeviceCloseIOValue, 0, 2, 15); err != nil {
							utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
						} else if timeout {
							utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "SaveOpenTime,1:etcd服务数据保存失败"))
						} else {
							amountFen, amountRecord, err := CalculateAmountType(snNum)
							if err != nil {
								utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "CalculateAmountType 失败"))
							}
							//1充满停止、2金额用完停止、3闲置停止、4汽车未允许充电停止、5拔出停止、6功率超限停止、7电量超限停止、8时间超限停止
							powerFinishOrder(snNum, 8, amountFen, duration, electricityKWH, amountRecord)
							return
						}
					}
				}
			}
		}
	}
}

func AnalyzePowerMessageType1_1(snNum, message string) {
	if isWorking, err := RedisGet(snNum+"/isWorking", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "checkState:1，etcd数据isWorking获取失败"))
	} else if isWorking == "1" {
		var mapResult map[string]string
		err := json.Unmarshal([]byte(message), &mapResult)
		if err != nil {
			utils.MyPrint(utils.PRINT_ERROR, err.Error())
		} else {
			if len(mapResult["power"]) == 20 {
				var power int
				var electricity int
				var voltage int
				var current int
				powerStr := []byte(mapResult["power"])
				power = int(powerStr[0] - '0')
				power <<= 4
				power |= int(powerStr[1] - '0')
				power <<= 4
				power |= int(powerStr[2] - '0')
				power <<= 4
				power |= int(powerStr[3] - '0')

				electricity = int(powerStr[4] - '0')
				electricity <<= 4
				electricity |= int(powerStr[5] - '0')
				electricity <<= 4
				electricity |= int(powerStr[6] - '0')
				electricity <<= 4
				electricity |= int(powerStr[7] - '0')
				electricity <<= 4
				electricity |= int(powerStr[8] - '0')
				electricity <<= 4
				electricity |= int(powerStr[9] - '0')
				electricity <<= 4
				electricity |= int(powerStr[10] - '0')
				electricity <<= 4
				electricity |= int(powerStr[11] - '0')

				voltage = int(powerStr[12] - '0')
				voltage <<= 4
				voltage |= int(powerStr[13] - '0')
				voltage <<= 4
				voltage |= int(powerStr[14] - '0')
				voltage <<= 4
				voltage |= int(powerStr[15] - '0')

				current = int(powerStr[16] - '0')
				current <<= 4
				current |= int(powerStr[17] - '0')
				current <<= 4
				current |= int(powerStr[18] - '0')
				current <<= 4
				current |= int(powerStr[19] - '0')

				electricityLastStr, err := RedisGet(snNum+"/electricity", "0")
				if err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
				}
				electricityLast, err := strconv.ParseFloat(electricityLastStr, 64)
				if err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
				}

				duration, err := AnalyzeDevDurationGet(snNum + "/openTime")
				if err != nil {
					utils.MyPrint(utils.PRINT_ERROR, err.Error())
				}
				electricityf := float64(electricity/3600) / 1000
				electricityf = processElectricity(electricityf)
				electricityKWH := getActualElectricity(snNum, electricityf, electricityLast, duration)

				powerKW := float64(power) / 1000
				voltageV := float64(voltage) / 100
				currentA := float64(current) / 1000

				if err = RedisSave(snNum+"/electricity", strconv.FormatFloat(electricityKWH, 'E', -1, 64)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, err.Error())
				}
				if err = MqttNoticeSend(snNum+"/electricity", strconv.FormatFloat(electricityKWH, 'E', -1, 64)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
				}
				if err = RedisSave(snNum+"/power", strconv.FormatFloat(powerKW, 'E', -1, 64)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, err.Error())
				}
				if err = MqttNoticeSend(snNum+"/power", strconv.FormatFloat(powerKW, 'E', -1, 64)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
				}
				if err = RedisSave(snNum+"/voltage", strconv.FormatFloat(voltageV, 'E', -1, 64)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, err.Error())
				}
				if err = MqttNoticeSend(snNum+"/voltage", strconv.FormatFloat(voltageV, 'E', -1, 64)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
				}
				if err = RedisSave(snNum+"/current", strconv.FormatFloat(currentA, 'E', -1, 64)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, err.Error())
				}
				if err = MqttNoticeSend(snNum+"/current", strconv.FormatFloat(currentA, 'E', -1, 64)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
				}
				var areadystop int64
				if duration > 300 {
					areadystop, _ = JudgeRestartDev(snNum, powerKW, electricityKWH, currentA)
				}

				//amountLastStr, err := RedisGet(snNum+"/amount", "0")
				// if err != nil {
				// 	utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
				// }

				// if err = MqttNoticeSend(snNum+"/amount", amountLastStr); err != nil {
				// 	utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
				// }

				// remainAmount, _ := RedisGet(snNum+"/remainAmount", "")

				// if err = MqttNoticeSend(snNum+"/remainAmount", remainAmount); err != nil {
				// 	utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
				// }

				// 保存上一次推送时间，以判断充电时间是否到达某一时刻，用于分时段计费
				if err = RedisSave(snNum+"/powerUpdateTime", time.Now().Format("2006-01-02 15:04:05")); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
				}

				var qldOutletControlJson models.QldOutletControlJson
				if qldOutletControlJsonStr, err1 := RedisGet(snNum+"/control", "{}"); err1 != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err1, "calculateAmount:3，获取设备etcd价格失败"))
				} else if err := json.Unmarshal([]byte(qldOutletControlJsonStr), &qldOutletControlJson); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err1, "calculateAmount:3，获取设备etcd价格失败"))
				} else {

					if err = MqttNoticeSend(snNum+"/amount", strconv.FormatInt(qldOutletControlJson.Money, 10)); err != nil {
						utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
					}
					if err = RedisSave(snNum+"/amount", strconv.FormatInt(qldOutletControlJson.Money, 10)); err != nil {
						utils.MyPrint(utils.PRINT_ERROR, err.Error())
					}
					amountRecord, err := CreateAmountRecord(snNum, electricityLastStr, qldOutletControlJson.Money)
					if err != nil {
						utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "生成消费记录失败"))
					}

					if err = RedisSave(snNum+"/amountRecord", amountRecord); err != nil {
						utils.MyPrint(utils.PRINT_ERROR, err.Error())
					}

					userIdStr, err := RedisGet(snNum+"/userId", "0")
					// 再获取该用户的balance
					balanceStr, err := RedisGetNoHeader("userBalance/"+userIdStr, "0")

					balance, err := strconv.ParseInt(balanceStr, 10, 64)

					if err = MqttNoticeSend(snNum+"/remainAmount", strconv.FormatInt(balance-qldOutletControlJson.Money, 10)); err != nil {
						utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
					}

					// 功率超限，自动结算
					// if qldOutletControlJson.MaxPower > 0 {
					// 	if powerLastStr, err := RedisGet(snNum+"/powerLast", "0"); err != nil {
					// 		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
					// 	} else if powerLast, err := strconv.ParseFloat(powerLastStr, 64); err != nil {
					// 		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
					// 	} else if powerKW > qldOutletControlJson.MaxPower && powerLast > qldOutletControlJson.MaxPower {
					// 		utils.MyPrint(utils.PRINT_WARN, "******************关闭设备******************")
					// 		if timeout, _, err := OperateDevice(snNum, OperateDeviceCloseIOValue, 0, 2, 15); err != nil {
					// 			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
					// 		} else if timeout {
					// 			utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "SaveOpenTime,1:etcd服务数据保存失败"))
					// 		} else {
					// 			//1充满停止、2金额用完停止、3闲置停止、4汽车未允许充电停止、5拔出停止、6功率超限停止、7电量超限停止、8时间超限停止
					// 			amountFen := qldOutletControlJson.Money

					// 			powerFinishOrder(snNum, 6, amountFen, duration, electricityKWH, string(amountRecord))
					// 			return
					// 		}
					// 	}
					// 	if err = RedisSave(snNum+"/powerLast", strconv.FormatFloat(powerKW, 'E', -1, 64)); err != nil {
					// 		utils.MyPrint(utils.PRINT_ERROR, err.Error())
					// 	}
					// }
					// 电量超限，自动结算
					// if qldOutletControlJson.MaxElectricity > 0 && electricityKWH > qldOutletControlJson.MaxElectricity {
					// 	utils.MyPrint(utils.PRINT_WARN, "******************关闭设备******************")
					// 	if timeout, _, err := OperateDevice(snNum, OperateDeviceCloseIOValue, 0, 2, 15); err != nil {
					// 		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
					// 	} else if timeout {
					// 		utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "SaveOpenTime,1:etcd服务数据保存失败"))
					// 	} else {
					// 		//1充满停止、2金额用完停止、3闲置停止、4汽车未允许充电停止、5拔出停止、6功率超限停止、7电量超限停止、8时间超限停止
					// 		amountFen := qldOutletControlJson.Money
					// 		powerFinishOrder(snNum, 7, amountFen, duration, electricityKWH, string(amountRecord))
					// 		return
					// 	}
					// }
					// 时间超限，自动结算
					if int64(qldOutletControlJson.MaxDuration) > 0 && duration > int64(qldOutletControlJson.MaxDuration) {
						utils.MyPrint(utils.PRINT_WARN, "******************关闭设备******************")
						if timeout, _, err := OperateDevice(snNum, OperateDeviceCloseIOValue, 0, 2, 15); err != nil {
							utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
						} else if timeout {
							utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "SaveOpenTime,1:etcd服务数据保存失败"))
						} else {
							//1充满停止、2金额用完停止、3闲置停止、4汽车未允许充电停止、5拔出停止、6功率超限停止、7电量超限停止、8时间超限停止

							stepelec, _ := RedisGet(snNum+"/stepelec", "0")
							if err != nil {
								errNew := utils.WrapError(err, "上次的电量获取失败")
								utils.MyPrint(utils.PRINT_ERROR, errNew.Msg())
							}
							var stepfloat float64
							if stepelec != "0" {
								stepfloat, _ = strconv.ParseFloat(stepelec, 64)

							}
							var ftemp float64
							if areadystop == 1 {
								ftemp = stepfloat
							} else {
								ftemp = electricityKWH + stepfloat
							}
							amountFen := qldOutletControlJson.Money
							powerFinishOrder(snNum, 8, amountFen, duration, ftemp, string(amountRecord))
							return
						}
					}
				}
			}
		}
	}
}

func AnalyzePowerMessageType2(snNum, message string) {
	if isWorking, err := RedisGet(snNum+"/isWorking", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "checkState:1，etcd数据isWorking获取失败"))
	} else if isWorking == "1" {
		var mapResult map[string]string
		err := json.Unmarshal([]byte(message), &mapResult)
		if err != nil {
			utils.MyPrint(utils.PRINT_ERROR, err.Error())
		} else {
			if len(mapResult["power"]) == 20 {
				var power int
				var electricity int
				var voltage int
				var current int
				powerStr := []byte(mapResult["power"])
				power = int(powerStr[0] - '0')
				power <<= 4
				power |= int(powerStr[1] - '0')
				power <<= 4
				power |= int(powerStr[2] - '0')
				power <<= 4
				power |= int(powerStr[3] - '0')

				electricity = int(powerStr[4] - '0')
				electricity <<= 4
				electricity |= int(powerStr[5] - '0')
				electricity <<= 4
				electricity |= int(powerStr[6] - '0')
				electricity <<= 4
				electricity |= int(powerStr[7] - '0')
				electricity <<= 4
				electricity |= int(powerStr[8] - '0')
				electricity <<= 4
				electricity |= int(powerStr[9] - '0')
				electricity <<= 4
				electricity |= int(powerStr[10] - '0')
				electricity <<= 4
				electricity |= int(powerStr[11] - '0')

				voltage = int(powerStr[12] - '0')
				voltage <<= 4
				voltage |= int(powerStr[13] - '0')
				voltage <<= 4
				voltage |= int(powerStr[14] - '0')
				voltage <<= 4
				voltage |= int(powerStr[15] - '0')

				current = int(powerStr[16] - '0')
				current <<= 4
				current |= int(powerStr[17] - '0')
				current <<= 4
				current |= int(powerStr[18] - '0')
				current <<= 4
				current |= int(powerStr[19] - '0')

				electricityKWH := float64(electricity/3600) / 1000
				electricityKWH = processElectricity(electricityKWH)
				if electricity == 0 {
					utils.MyPrint(utils.PRINT_WARN, "电量为0，使用之前的旧值")
					if electricityLastStr, err := RedisGet(snNum+"/electricity", "0"); err != nil {
						utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzePowerMessageType2,1:etcd服务电费数据获取失败"))
					} else if electricityLast, err := strconv.ParseFloat(electricityLastStr, 64); err != nil {
						utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzePowerMessageType2,1:etcd服务电费数据获取失败"))
					} else {
						electricityKWH = electricityLast
					}
				}

				duration, err := AnalyzeDevDurationGet(snNum + "/openTime")
				if err != nil {
					utils.MyPrint(utils.PRINT_ERROR, err.Error())
				}
				amountFen, err := calculateAmount(snNum, electricityKWH, duration, 0)
				if err != nil {
					utils.MyPrint(utils.PRINT_ERROR, err.Error())
				}
				powerKW := float64(power) / 1000
				voltageV := float64(voltage) / 100
				currentA := float64(current) / 1000

				if err = RedisSave(snNum+"/electricity", strconv.FormatFloat(electricityKWH, 'E', -1, 64)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, err.Error())
				}
				if err = MqttNoticeSend(snNum+"/electricity", strconv.FormatFloat(electricityKWH, 'E', -1, 64)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
				}
				if err = RedisSave(snNum+"/power", strconv.FormatFloat(powerKW, 'E', -1, 64)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, err.Error())
				}
				if err = MqttNoticeSend(snNum+"/power", strconv.FormatFloat(powerKW, 'E', -1, 64)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
				}
				if err = RedisSave(snNum+"/voltage", strconv.FormatFloat(voltageV, 'E', -1, 64)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, err.Error())
				}
				if err = MqttNoticeSend(snNum+"/voltage", strconv.FormatFloat(voltageV, 'E', -1, 64)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
				}
				if err = RedisSave(snNum+"/current", strconv.FormatFloat(currentA, 'E', -1, 64)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, err.Error())
				}
				if err = MqttNoticeSend(snNum+"/current", strconv.FormatFloat(currentA, 'E', -1, 64)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
				}

				amountLastStr, err := RedisGet(snNum+"/amount", "0")
				if err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
				}
				amountLast, err := strconv.ParseInt(amountLastStr, 10, 64)
				if err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,2:etcd服务电费数据转换失败"))
				}
				amountRecordLast, err := RedisGet(snNum+"/amountRecord", "")
				if err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
				}
				if err = RedisSave(snNum+"/amount", strconv.FormatInt(amountFen, 10)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, err.Error())
				}
				if err = MqttNoticeSend(snNum+"/amount", strconv.FormatInt(amountFen, 10)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
				}
				amountRecord, err := CalculateAmountRecord(snNum)
				if err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "OutLetClose关闭设备:10，活动订单sn失败"))
					return
				}
				if err = RedisSave(snNum+"/amountRecord", amountRecord); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, err.Error())
				}
				remainAmount, err := calculateRemainAmount(snNum) // 必须在amount保存的后面
				if err = RedisSave(snNum+"/remainAmount", strconv.FormatInt(remainAmount, 10)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, err.Error())
				}
				if err = MqttNoticeSend(snNum+"/remainAmount", strconv.FormatInt(remainAmount, 10)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
				}

				// 读取上一次推送时间，以判断充电时间是否到达某一时刻，用于分时段计费
				//powerLastUpdateTime := timeNow
				//if powerLastUpdateTimeStr,err := RedisGet(snNum+"/powerUpdateTime"); err != nil {
				//	utils.MyPrint(utils.PRINT_ERROR , utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
				//}else if len(powerLastUpdateTimeStr)>0 {
				//	if powerLastUpdateTime, err = time.Parse("2006-01-02 15:04:05", powerLastUpdateTimeStr);err != nil {
				//		errNew := utils.WrapError(err, "AnalyzeDevPowerDurationGet,2:etcd服务设备打开时间数据转换失败")
				//		utils.MyPrint(utils.PRINT_ERROR , errNew.Msg())
				//	}
				//}
				// 保存上一次推送时间，以判断充电时间是否到达某一时刻，用于分时段计费
				if err = RedisSave(snNum+"/powerUpdateTime", time.Now().Format("2006-01-02 15:04:05")); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
				}

				// 设置金额用完，自动结算
				if openAmountStr, err := RedisGet(snNum+"/openAmount", "0"); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzePowerMessageType0,5:RedisGet充满停止，num="+snNum))
				} else if openAmount, err := strconv.ParseInt(openAmountStr, 10, 64); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "OutLetClose关闭设备:10，活动订单sn失败"))
				} else {
					if openAmount > 0 && amountFen > openAmount {
						utils.MyPrint(utils.PRINT_WARN, "******************关闭设备******************")
						if timeout, operateFlag, err := OperateDevice(snNum, OperateDeviceCloseIOValue, 0, 2, 15); err != nil {
							utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
						} else if timeout {
							utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "SaveOpenTime,1:etcd服务数据保存失败"))
						} else if operateFlag != 0 {
							utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "SaveOpenTime,1:etcd服务数据保存失败"))
						} else {
							//1充满停止、2金额用完停止、3闲置停止、4汽车未允许充电停止、5拔出停止、6功率超限停止、7电量超限停止、8时间超限停止
							powerFinishOrder(snNum, 2, amountLast, duration, electricityKWH, amountRecordLast)
							return
						}
					}
				}

				// 余额不足，自动结算
				if remainAmount < 0 {
					utils.MyPrint(utils.PRINT_WARN, "******************关闭设备******************")
					if timeout, operateFlag, err := OperateDevice(snNum, OperateDeviceCloseIOValue, 0, 2, 15); err != nil {
						utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
					} else if timeout {
						utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "SaveOpenTime,1:etcd服务数据保存失败"))
					} else if operateFlag != 0 {
						utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "SaveOpenTime,1:etcd服务数据保存失败"))
					} else {
						//1充满停止、2金额用完停止、3闲置停止、4汽车未允许充电停止、5拔出停止、6功率超限停止、7电量超限停止、8时间超限停止
						powerFinishOrder(snNum, 2, amountLast, duration, electricityKWH, amountRecordLast)
						return
					}
				}

				var qldOutletControlJson models.QldOutletControlJson
				if qldOutletControlJsonStr, err1 := RedisGet(snNum+"/control", "{}"); err1 != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err1, "calculateAmount:3，获取设备etcd价格失败"))
				} else if err := json.Unmarshal([]byte(qldOutletControlJsonStr), &qldOutletControlJson); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err1, "calculateAmount:3，获取设备etcd价格失败"))
				} else {
					// 余额不足10元，每20分钟通知
					if remainAmount < qldOutletControlJson.BalanceShort {
						if remainAmountShortNoticeTimeStr, err := RedisGet(snNum+"/remainAmountShortNoticeTime", ""); err != nil {
							utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
						} else if len(remainAmountShortNoticeTimeStr) == 0 {
							//通知余额不足20元
							if userIdStr, err := RedisGet(snNum+"/userId", "0"); err != nil {
								utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
							} else if userId, err1 := strconv.ParseInt(userIdStr, 10, 64); err1 != nil {
								utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err1, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
							} else {
								BalanceWeiXinMassage(userId, remainAmount, "余额不足"+strconv.FormatFloat(float64(qldOutletControlJson.BalanceShort)/100, 'E', -1, 64)+"元，请及时充值。")
								BalanceWeiXinMassageGdt(userId, remainAmount, "余额不足"+strconv.FormatFloat(float64(qldOutletControlJson.BalanceShort)/100, 'E', -1, 64)+"元，请及时充值。")
								BalanceAliMassageGdt(userId, remainAmount, "余额不足"+strconv.FormatFloat(float64(qldOutletControlJson.BalanceShort)/100, 'E', -1, 64)+"元，请及时充值。")
							}

							if err = RedisSave(snNum+"/remainAmountShortNoticeTime", time.Now().Format("2006-01-02 15:04:05")); err != nil {
								utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
							}
						} else if remainAmountShortNoticeTime, err := time.Parse("2006-01-02 15:04:05", remainAmountShortNoticeTimeStr); err != nil {
							errNew := utils.WrapError(err, "AnalyzeDevPowerDurationGet,2:etcd服务设备打开时间数据转换失败")
							utils.MyPrint(utils.PRINT_ERROR, errNew.Msg())
						} else if time.Now().Sub(remainAmountShortNoticeTime) > (time.Second * time.Duration(qldOutletControlJson.PushBalanceShortDuration)) {
							if userIdStr, err := RedisGet(snNum+"/userId", "0"); err != nil {
								utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
							} else if userId, err1 := strconv.ParseInt(userIdStr, 10, 64); err1 != nil {
								utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err1, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
							} else {
								BalanceWeiXinMassage(userId, remainAmount, "余额不足"+strconv.FormatFloat(float64(qldOutletControlJson.BalanceShort)/100, 'E', -1, 64)+"元，请及时充值。")
								BalanceWeiXinMassageGdt(userId, remainAmount, "余额不足"+strconv.FormatFloat(float64(qldOutletControlJson.BalanceShort)/100, 'E', -1, 64)+"元，请及时充值。")
								BalanceAliMassageGdt(userId, remainAmount, "余额不足"+strconv.FormatFloat(float64(qldOutletControlJson.BalanceShort)/100, 'E', -1, 64)+"元，请及时充值。")
							}

							if err = RedisSave(snNum+"/remainAmountShortNoticeTime", time.Now().Format("2006-01-02 15:04:05")); err != nil {
								utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
							}
						}
					}
					// 功率超限，自动结算
					if qldOutletControlJson.MaxPower > 0 && powerKW > qldOutletControlJson.MaxPower {
						utils.MyPrint(utils.PRINT_WARN, "******************关闭设备******************")
						if timeout, operateFlag, err := OperateDevice(snNum, OperateDeviceCloseIOValue, 0, 2, 15); err != nil {
							utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
						} else if timeout {
							utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "SaveOpenTime,1:etcd服务数据保存失败"))
						} else if operateFlag != 0 {
							utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "SaveOpenTime,1:etcd服务数据保存失败"))
						} else {
							//1充满停止、2金额用完停止、3闲置停止、4汽车未允许充电停止、5拔出停止、6功率超限停止、7电量超限停止、8时间超限停止
							powerFinishOrder(snNum, 6, amountFen, duration, electricityKWH, amountRecord)
							return
						}
					}
					// 电量超限，自动结算
					if qldOutletControlJson.MaxElectricity > 0 && electricityKWH > qldOutletControlJson.MaxElectricity {
						utils.MyPrint(utils.PRINT_WARN, "******************关闭设备******************")
						if timeout, operateFlag, err := OperateDevice(snNum, OperateDeviceCloseIOValue, 0, 2, 15); err != nil {
							utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
						} else if timeout {
							utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "SaveOpenTime,1:etcd服务数据保存失败"))
						} else if operateFlag != 0 {
							utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "SaveOpenTime,1:etcd服务数据保存失败"))
						} else {
							//1充满停止、2金额用完停止、3闲置停止、4汽车未允许充电停止、5拔出停止、6功率超限停止、7电量超限停止、8时间超限停止
							powerFinishOrder(snNum, 7, amountFen, duration, electricityKWH, amountRecord)
							return
						}
					}
					// 时间超限，自动结算
					if int64(qldOutletControlJson.MaxDuration) > 0 && duration > int64(qldOutletControlJson.MaxDuration) {
						utils.MyPrint(utils.PRINT_WARN, "******************关闭设备******************")
						if timeout, operateFlag, err := OperateDevice(snNum, OperateDeviceCloseIOValue, 0, 2, 15); err != nil {
							utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
						} else if timeout {
							utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "SaveOpenTime,1:etcd服务数据保存失败"))
						} else if operateFlag != 0 {
							utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "SaveOpenTime,1:etcd服务数据保存失败"))
						} else {
							//1充满停止、2金额用完停止、3闲置停止、4汽车未允许充电停止、5拔出停止、6功率超限停止、7电量超限停止、8时间超限停止
							powerFinishOrder(snNum, 8, amountFen, duration, electricityKWH, amountRecord)
							return
						}
					}
				}
			}
		}
	}
}

func AnalyzePowerMessageType4(snNum, message string) (response string) {
	response = "{\"data\":\"ok\"}"
	if isWorking, err := RedisGet(snNum+"/isWorking", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "checkState:1，etcd数据isWorking获取失败"))
	} else if isWorking == "1" {
		response = "{\"data\":\"" + isWorking + "\"}"
		if len(message) == 0 {
			utils.MyPrint(utils.PRINT_WARN, "设备状态错误,"+snNum)
			return
		}
		result := strings.Split(message, ",")
		if len(result) < 1 {
			utils.MyPrint(utils.PRINT_WARN, "设备状态错误0,"+snNum)
			return
		}
		voltageV, err := strconv.ParseFloat(result[0], 64)
		if err != nil {
			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzePowerMessageNew,1:电压数据转换失败"))
		}
		if len(result) < 2 {
			utils.MyPrint(utils.PRINT_WARN, "设备状态错误1,"+snNum)
			return
		}
		currentA, err := strconv.ParseFloat(result[1], 64)
		if err != nil {
			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzePowerMessageNew,2:电流数据转换失败"))
		}
		if len(result) < 3 {
			utils.MyPrint(utils.PRINT_WARN, "设备状态错误2,"+snNum)
			return
		}
		power, err := strconv.ParseFloat(result[2], 64)
		if err != nil {
			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzePowerMessageNew,3:功率数据转换失败"))
		}
		powerKW := power / 1000
		if len(result) < 4 {
			utils.MyPrint(utils.PRINT_WARN, "设备状态错误3,"+snNum)
			return
		}
		electricityKWH, err := strconv.ParseFloat(result[3], 64)
		electricityKWH = processElectricity(electricityKWH)
		if err != nil {
			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzePowerMessageNew,3:功率数据转换失败"))
		}

		duration, err := AnalyzeDevDurationGet(snNum + "/openTime")
		if err != nil {
			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzePowerMessageNew,3:功率数据转换失败"))
		}
		openType, err := GetOpenType(snNum)
		if err != nil {
			utils.WrapError(err, "OutLetClose关闭设备:10，活动订单sn失败")
		}

		electricityLastStr, err := RedisGet(snNum+"/electricity", "0")
		if err != nil {
			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
		}
		electricityLast, err := strconv.ParseFloat(electricityLastStr, 64)
		if err != nil {
			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
		}
		electricityKWH = getActualElectricity(snNum, electricityKWH, electricityLast, duration)

		amountFen, err := calculateAmount(snNum, electricityKWH, duration, openType)
		if err != nil {
			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzePowerMessageNew,3:功率数据转换失败"))
		}

		utils.MyPrint(utils.PRINT_WARN, electricityKWH, powerKW, voltageV, currentA, amountFen)
		OrderSn, err1 := SpecialOrderSnGet(snNum+"/orderSn", "")
		userId, err2 := RedisGet(snNum+"/userId", "0")
		if err1 != nil || err2 != nil { // 订单结束之后就不推送
			if err1 != nil {
				utils.MyPrint(utils.PRINT_ERROR, err1)
			}
			if err2 != nil {
				utils.MyPrint(utils.PRINT_ERROR, err2.Error())
			}
		} else {
			_ = RedisSave(snNum+"/electricity", strconv.FormatFloat(electricityKWH, 'E', -1, 64))
			if err = MqttNoticeSend(snNum+"/electricity", strconv.FormatFloat(electricityKWH, 'E', -1, 64)); err != nil {
				utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
			}
			_ = RedisSave(snNum+"/power", strconv.FormatFloat(powerKW, 'E', -1, 64))
			if err = MqttNoticeSend(snNum+"/power", strconv.FormatFloat(powerKW, 'E', -1, 64)); err != nil {
				utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
			}
			_ = RedisSave(snNum+"/voltage", strconv.FormatFloat(voltageV, 'E', -1, 64))
			if err = MqttNoticeSend(snNum+"/voltage", strconv.FormatFloat(voltageV, 'E', -1, 64)); err != nil {
				utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
			}
			_ = RedisSave(snNum+"/current", strconv.FormatFloat(currentA, 'E', -1, 64))
			if err = MqttNoticeSend(snNum+"/current", strconv.FormatFloat(currentA, 'E', -1, 64)); err != nil {
				utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
			}

			amountLastStr, err := RedisGet(snNum+"/amount", "0")
			if err != nil {
				utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
			}
			amountLast, err := strconv.ParseInt(amountLastStr, 10, 64)
			if err != nil {
				utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,2:etcd服务电费数据转换失败"))
			}
			amountRecordLast, err := RedisGet(snNum+"/amountRecord", "")
			if err != nil {
				utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
			}
			if err = RedisSave(snNum+"/amount", strconv.FormatInt(amountFen, 10)); err != nil {
				utils.MyPrint(utils.PRINT_ERROR, err.Error())
			}
			if err = MqttNoticeSend(snNum+"/amount", strconv.FormatInt(amountFen, 10)); err != nil {
				utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
			}
			amountRecord, err := CalculateAmountRecord(snNum)
			if err != nil {
				utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "OutLetClose关闭设备:10，活动订单sn失败"))
				return
			}
			if err = RedisSave(snNum+"/amountRecord", amountRecord); err != nil {
				utils.MyPrint(utils.PRINT_ERROR, err.Error())
			}
			remainAmount, _ := calculateRemainAmount(snNum) // 必须在amount保存的后面
			_ = RedisSave(snNum+"/remainAmount", strconv.FormatInt(remainAmount, 10))
			if err = MqttNoticeSend(snNum+"/remainAmount", strconv.FormatInt(remainAmount, 10)); err != nil {
				utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
			}

			batteryTypeStr, err := RedisGet(snNum+"/batteryType", "1")
			if err != nil {
				utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "OutLetOpen: 13，redis保存设备价格失败"))
			}
			batteryType, err := strconv.ParseInt(batteryTypeStr, 10, 64)
			if err != nil {
				utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,2:etcd服务电费数据转换失败"))
			}
			soc, dSoc, timeLeft, _ := GetSOCValue(float32(currentA), float32(voltageV), GetOutletCurrentIn(snNum), userId, OrderSn, 30, batteryType)
			utils.MyPrint(utils.PRINT_WARN, float32(currentA), float32(voltageV), GetOutletCurrentIn(snNum), userId, OrderSn, 30, soc, dSoc, timeLeft)
			_ = RedisSave(snNum+"/soc", strconv.FormatFloat(float64(soc), 'E', -1, 64))
			if err = MqttNoticeSend(snNum+"/soc", strconv.FormatFloat(float64(soc), 'E', -1, 64)); err != nil {
				utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
			}
			_ = RedisSave(snNum+"/dSoc", strconv.FormatFloat(float64(dSoc), 'E', -1, 64))
			if err = MqttNoticeSend(snNum+"/dSoc", strconv.FormatFloat(float64(dSoc), 'E', -1, 64)); err != nil {
				utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
			}
			_ = RedisSave(snNum+"/timeLeft", strconv.FormatInt(int64(timeLeft), 10))
			if err = MqttNoticeSend(snNum+"/timeLeft", strconv.FormatInt(int64(timeLeft), 10)); err != nil {
				utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
			}

			// 余额不足，自动结算
			if remainAmount < 0 {
				utils.MyPrint(utils.PRINT_WARN, "******************关闭设备******************")
				if timeout, _, err := OperateDevice(snNum, OperateDeviceCloseIOValue, 0, 2, 15); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
				} else if timeout {
					utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "AnalyzePowerMessageType4,1:关闭应答超时"))
				} else {
					//1充满停止、2金额用完停止、3闲置停止、4汽车未允许充电停止、5拔出停止、6功率超限停止、7电量超限停止、8时间超限停止
					powerFinishOrder(snNum, 2, amountLast, duration, electricityKWH, amountRecordLast)
					return
				}
			}

			var qldOutletControlJson models.QldOutletControlJson
			if qldOutletControlJsonStr, err1 := RedisGet(snNum+"/control", "{}"); err1 != nil {
				utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err1, "calculateAmount:3，获取设备etcd价格失败"))
			} else if err := json.Unmarshal([]byte(qldOutletControlJsonStr), &qldOutletControlJson); err != nil {
				utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err1, "calculateAmount:3，获取设备etcd价格失败"))
			} else {
				//若电流未达到充满标准，更新时间
				if currentA > qldOutletControlJson.ChargeFullLowCurrent {
					if err = RedisSave(snNum+"/powerCurrentStartLowTime", time.Now().Format("2006-01-02 15:04:05")); err != nil {
						utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
					}
				}
				// 读取开始充满低电流的时长，以根据电流判断是否充满电
				powerPowerStartLowTimeDuration, err := AnalyzeDevDurationGet(snNum + "/powerCurrentStartLowTime")
				if err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerDurationGet,2:etcd服务设备打开时间数据转换失败"))
				}
				// 充满低电流持续，认为充满
				if powerPowerStartLowTimeDuration > qldOutletControlJson.ChargeFullKeepDuration {
					if err = RedisSave(snNum+"/powerPowerStartLowTime", time.Now().Format("2006-01-02 15:04:05")); err != nil {
						utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
					} else {
						if orderSn, err := SpecialOrderSnGet(snNum+"/orderSn", ""); err != nil {
							utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "finishOrder:1，orderSn获取失败"))
						} else if userIdStr, err := RedisGet(snNum+"/userId", "0"); err != nil {
							utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "finishOrder:9，userId获取失败"))
						} else if err = ResetSoc(snNum, userIdStr, orderSn); err != nil {
							utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "OutLetClose关闭设备:11，重置SOC失败"))
						}
						utils.MyPrint(utils.PRINT_WARN, "******************关闭设备******************")
						if timeout, _, err := OperateDevice(snNum, OperateDeviceCloseIOValue, 0, 2, 15); err != nil {
							utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
						} else if timeout {
							utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "AnalyzePowerMessageType4,1:关闭应答超时"))
						} else {
							//1充满停止、2金额用完停止、3闲置停止、4汽车未允许充电停止、5拔出停止、6功率超限停止、7电量超限停止、8时间超限停止
							powerFinishOrder(snNum, 1, amountFen, duration, electricityKWH, amountRecord)
							return
						}
					}
				}
			}
		}
	} else {
		response = "{\"data\":\"" + isWorking + "\"}"
	}
	return
}

func AnalyzePowerMessageType5_1(snNum, message string) (response string) {
	response = "{\"data\":\"ok\"}"
	if isWorking, err := RedisGet(snNum+"/isWorking", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "checkState:1，etcd数据isWorking获取失败"))
	} else if isWorking == "1" {
		response = "{\"data\":\"" + isWorking + "\"}"
		if len(message) == 0 {
			utils.MyPrint(utils.PRINT_WARN, "设备状态错误,"+snNum)
			return
		}
		result := strings.Split(message, ",")
		if len(result) < 1 {
			utils.MyPrint(utils.PRINT_WARN, "设备状态错误0,"+snNum)
			return
		}
		voltageV, err := strconv.ParseFloat(result[0], 64)
		if err != nil {
			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzePowerMessageNew,1:电压数据转换失败"))
		}
		if len(result) < 2 {
			utils.MyPrint(utils.PRINT_WARN, "设备状态错误1,"+snNum)
			return
		}
		currentA, err := strconv.ParseFloat(result[1], 64)
		if err != nil {
			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzePowerMessageNew,2:电流数据转换失败"))
		}
		if len(result) < 3 {
			utils.MyPrint(utils.PRINT_WARN, "设备状态错误2,"+snNum)
			return
		}
		power, err := strconv.ParseFloat(result[2], 64)
		if err != nil {
			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzePowerMessageNew,3:功率数据转换失败"))
		}
		//获取最大的功率,存储到redis里面_start
		//先获取最大功率里面的值
		if MaxPowerStr, err1 := RedisGet(snNum+"/maxPower", "0"); err1 == nil {
			MaxPower, err2 := strconv.ParseFloat(MaxPowerStr, 64)
			if err2 == nil {
				//		//进行判断
				if power > MaxPower {
					utils.MyPrint(utils.PRINT_WARN, "桩号:", snNum, "原来的功率:", MaxPower, "最新功率:", power)
					//存进redis
					_ = RedisSave(snNum+"/maxPower", result[2])
				}
			}

		}
		//获取最大的功率,存储到redis里面_end
		powerKW := power / 1000
		if len(result) < 4 {
			utils.MyPrint(utils.PRINT_WARN, "设备状态错误3,"+snNum)
			return
		}
		electricityKWH, err := strconv.ParseFloat(result[3], 64)
		electricityKWH = processElectricity(electricityKWH)
		if err != nil {
			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzePowerMessageNew,3:功率数据转换失败"))
		}

		duration, err := AnalyzeDevDurationGet(snNum + "/openTime")
		if err != nil {
			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzePowerMessageNew,3:功率数据转换失败"))
		}
		// openType, err := GetOpenType(snNum)
		// if err != nil {
		// 	utils.WrapError(err, "OutLetClose关闭设备:10，活动订单sn失败")
		// }

		electricityLastStr, err := RedisGet(snNum+"/electricity", "0")
		if err != nil {
			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
		}
		// electricityLast, err := strconv.ParseFloat(electricityLastStr, 64)
		// if err != nil {
		// 	utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
		// }
		// electricityKWH = getActualElectricity(snNum, electricityKWH, electricityLast, duration)

		utils.MyPrint(utils.PRINT_WARN, electricityKWH, powerKW, voltageV, currentA)
		_ = RedisSave(snNum+"/electricity", strconv.FormatFloat(electricityKWH, 'E', -1, 64))
		if err = MqttNoticeSend(snNum+"/electricity", strconv.FormatFloat(electricityKWH, 'E', -1, 64)); err != nil {
			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
		}
		_ = RedisSave(snNum+"/power", strconv.FormatFloat(powerKW, 'E', -1, 64))
		if err = MqttNoticeSend(snNum+"/power", strconv.FormatFloat(powerKW, 'E', -1, 64)); err != nil {
			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
		}
		_ = RedisSave(snNum+"/voltage", strconv.FormatFloat(voltageV, 'E', -1, 64))
		if err = MqttNoticeSend(snNum+"/voltage", strconv.FormatFloat(voltageV, 'E', -1, 64)); err != nil {
			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
		}
		_ = RedisSave(snNum+"/current", strconv.FormatFloat(currentA, 'E', -1, 64))
		if err = MqttNoticeSend(snNum+"/current", strconv.FormatFloat(currentA, 'E', -1, 64)); err != nil {
			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
		}
		var areadystop int64
		if duration > 300 {
			areadystop, _ = JudgeRestartDev(snNum, powerKW, electricityKWH, currentA)
		}

		var qldOutletControlJson models.QldOutletControlJson
		if qldOutletControlJsonStr, err1 := RedisGet(snNum+"/control", "{}"); err1 != nil {
			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err1, "calculateAmount:3，获取设备etcd价格失败"))
		} else if err := json.Unmarshal([]byte(qldOutletControlJsonStr), &qldOutletControlJson); err != nil {
			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err1, "calculateAmount:3，获取设备etcd价格失败"))
		} else {

			// amountLastStr, err := RedisGet(snNum+"/amount", "0")
			// if err != nil {
			// 	utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
			// }

			if err = MqttNoticeSend(snNum+"/amount", strconv.FormatInt(qldOutletControlJson.Money, 10)); err != nil {
				utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
			}
			if err = RedisSave(snNum+"/amount", strconv.FormatInt(qldOutletControlJson.Money, 10)); err != nil {
				utils.MyPrint(utils.PRINT_ERROR, err.Error())
			}

			amountRecord, err := CreateAmountRecord(snNum, electricityLastStr, qldOutletControlJson.Money)
			if err != nil {
				utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "生成消费记录失败"))
			}
			if err = RedisSave(snNum+"/amountRecord", amountRecord); err != nil {
				utils.MyPrint(utils.PRINT_ERROR, err.Error())
			}

			userIdStr, err := RedisGet(snNum+"/userId", "0")

			// 再获取该用户的balance
			balanceStr, err := RedisGetNoHeader("userBalance/"+userIdStr, "0")

			balance, err := strconv.ParseInt(balanceStr, 10, 64)

			if err = MqttNoticeSend(snNum+"/remainAmount", strconv.FormatInt(balance-qldOutletControlJson.Money, 10)); err != nil {
				utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
			}

			// 功率超限，自动结算
			// if qldOutletControlJson.MaxPower > 0 {
			// 	if powerLastStr, err := RedisGet(snNum+"/powerLast", "0"); err != nil {
			// 		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
			// 	} else if powerLast, err := strconv.ParseFloat(powerLastStr, 64); err != nil {
			// 		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
			// 	} else if powerKW > qldOutletControlJson.MaxPower && powerLast > qldOutletControlJson.MaxPower {
			// 		utils.MyPrint(utils.PRINT_WARN, "******************关闭设备******************")
			// 		if timeout, _, err := OperateDevice(snNum, OperateDeviceCloseIOValue, 0, 2, 15); err != nil {
			// 			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
			// 		} else if timeout {
			// 			utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "SaveOpenTime,1:etcd服务数据保存失败"))
			// 		} else {
			// 			//1充满停止、2金额用完停止、3闲置停止、4汽车未允许充电停止、5拔出停止、6功率超限停止、7电量超限停止、8时间超限停止
			// 			amountFen := qldOutletControlJson.Money

			// 			powerFinishOrder(snNum, 6, amountFen, duration, electricityKWH, string(amountRecord))
			// 			return
			// 		}
			// 	}
			// 	if err = RedisSave(snNum+"/powerLast", strconv.FormatFloat(powerKW, 'E', -1, 64)); err != nil {
			// 		utils.MyPrint(utils.PRINT_ERROR, err.Error())
			// 	}
			// }
			// 电量超限，自动结算
			// if qldOutletControlJson.MaxElectricity > 0 && electricityKWH > qldOutletControlJson.MaxElectricity {
			// 	utils.MyPrint(utils.PRINT_WARN, "******************关闭设备******************")
			// 	if timeout, _, err := OperateDevice(snNum, OperateDeviceCloseIOValue, 0, 2, 15); err != nil {
			// 		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
			// 	} else if timeout {
			// 		utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "SaveOpenTime,1:etcd服务数据保存失败"))
			// 	} else {
			// 		//1充满停止、2金额用完停止、3闲置停止、4汽车未允许充电停止、5拔出停止、6功率超限停止、7电量超限停止、8时间超限停止
			// 		amountFen := qldOutletControlJson.Money
			// 		powerFinishOrder(snNum, 7, amountFen, duration, electricityKWH, string(amountRecord))
			// 		return
			// 	}
			// }
			// 时间超限，自动结算
			if int64(qldOutletControlJson.MaxDuration) > 0 && duration > int64(qldOutletControlJson.MaxDuration) {
				utils.MyPrint(utils.PRINT_WARN, "******************关闭设备******************")
				if timeout, _, err := OperateDevice(snNum, OperateDeviceCloseIOValue, 0, 2, 15); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
				} else if timeout {
					utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "SaveOpenTime,1:etcd服务数据保存失败"))
				} else {
					//1充满停止、2金额用完停止、3闲置停止、4汽车未允许充电停止、5拔出停止、6功率超限停止、7电量超限停止、8时间超限停止

					stepelec, _ := RedisGet(snNum+"/stepelec", "0")
					if err != nil {
						errNew := utils.WrapError(err, "上次的电量获取失败")
						utils.MyPrint(utils.PRINT_ERROR, errNew.Msg())
					}
					var stepfloat float64
					if stepelec != "0" {
						stepfloat, _ = strconv.ParseFloat(stepelec, 64)

					}
					var ftemp float64
					if areadystop == 1 {
						ftemp = stepfloat
					} else {
						ftemp = electricityKWH + stepfloat
					}
					amountFen := qldOutletControlJson.Money
					powerFinishOrder(snNum, 8, amountFen, duration, ftemp, string(amountRecord))
					return
				}
			}
		}
	} else {
		response = "{\"data\":\"" + isWorking + "\"}"
	}
	return
}

func CalculateAmountType(snNum string) (int64, string, error) {
	duration, err := AnalyzeDevDurationGet(snNum + "/openTime")
	if err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzePowerMessageNew,3:功率数据转换失败"))
		return 0, "", nil
	}
	openType, err := GetOpenType(snNum)
	if err != nil {
		utils.WrapError(err, "OutLetClose关闭设备:10，活动订单sn失败")
		return 0, "", nil
	}

	electricityLastStr, err := RedisGet(snNum+"/electricity", "0")
	if err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
		return 0, "", nil
	}
	electricityLast, err := strconv.ParseFloat(electricityLastStr, 64)
	if err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
		return 0, "", nil
	}

	amountFen, err := calculateAmount(snNum, electricityLast, duration, openType)
	if err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzePowerMessageNew,3:功率数据转换失败"))
		return 0, "", nil
	}
	amountRecord, err := CalculateAmountRecord(snNum)
	if err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "CalculateAmountRecord,err "))
		return 0, "", nil
	}

	return amountFen, amountRecord, nil
}

func processElectricity(ele float64) float64 {
	xiShu, err := RedisGetNoHeader("DianSunXiShu", "1")
	if err != nil {
		utils.MyPrint(utils.PRINT_ERROR, "get dianSunXiShu fail")
	} else {
		xi, err := strconv.ParseFloat(xiShu, 64)
		if err != nil {
			utils.MyPrint(utils.PRINT_ERROR, "get dianSunXiShu fail")
		} else {
			if xi < 1 {
				xi = 1.02
			}
			ele = ele * xi
		}
	}

	return ele
}
func SetPowerToRedis(power float64, SnNum string) error {
	//先从redis里面获取功率list 判断是否大于10个数字
	PowerList, err := RedisGetNoHeaderList("/qld2pricecalculationservice/" + SnNum + "/ListPower")
	if err != nil {
		return errors.New("redis获取list数据失败了")
	}
	if len(PowerList) < 10 {
		//	将功率存到redis中
		if err := RedisSaveNoHeaderList("/qld2pricecalculationservice/"+SnNum+"/ListPower", strconv.FormatFloat(power, 'f', 6, 64)); err != nil {
			return errors.New("redis数据存入失败")
		}
	}
	return nil
}
func AnalyzePowerMessageType5(snNum, message string) (response string) {
	response = "{\"data\":\"ok\"}"
	if isWorking, err := RedisGet(snNum+"/isWorking", "0"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "checkState:1，etcd数据isWorking获取失败"))
	} else if isWorking == "1" {
		response = "{\"data\":\"" + isWorking + "\"}"
		if len(message) == 0 {
			utils.MyPrint(utils.PRINT_WARN, "设备状态错误,"+snNum)
			return
		}
		result := strings.Split(message, ",")
		if len(result) < 1 {
			utils.MyPrint(utils.PRINT_WARN, "设备状态错误0,"+snNum)
			return
		}
		voltageV, err := strconv.ParseFloat(result[0], 64)
		if err != nil {
			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzePowerMessageNew,1:电压数据转换失败"))
		}
		if len(result) < 2 {
			utils.MyPrint(utils.PRINT_WARN, "设备状态错误1,"+snNum)
			return
		}
		currentA, err := strconv.ParseFloat(result[1], 64)
		if err != nil {
			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzePowerMessageNew,2:电流数据转换失败"))
		}
		if len(result) < 3 {
			utils.MyPrint(utils.PRINT_WARN, "设备状态错误2,"+snNum)
			return
		}
		power, err := strconv.ParseFloat(result[2], 64)
		if err != nil {
			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzePowerMessageNew,3:功率数据转换失败"))
		}
		//获取最大的功率,存储到redis里面_start
		//先获取最大功率里面的值
		if MaxPowerStr, err1 := RedisGet(snNum+"/maxPower", "0"); err1 == nil {
			MaxPower, err2 := strconv.ParseFloat(MaxPowerStr, 64)
			if err2 == nil {
				//		//进行判断
				if power > MaxPower {
					utils.MyPrint(utils.PRINT_WARN, "桩号:", snNum, "原来的功率:", MaxPower, "最新功率:", power)
					//			//存进redis
					_ = RedisSave(snNum+"/maxPower", result[2])
				}
			}

		}
		//获取最大的功率,存储到redis里面_end
		powerKW := power / 1000
		if len(result) < 4 {
			utils.MyPrint(utils.PRINT_WARN, "设备状态错误3,"+snNum)
			return
		}
		electricityKWH, err := strconv.ParseFloat(result[3], 64)

		//start
		areaElecFactorBtn := false
		areaIdStr, err := RedisGet(snNum+"/areaId", "0")
		if err == nil && areaIdStr != "0" {
			devType, err := getDevType(snNum)
			if err == nil {
				if devType == 5 {
					exist, err := RedisCheckNoHeader("/area/elecFactor/AcChargingPile/" + areaIdStr)
					if exist && err == nil {
						areaElecFactorStr, err := RedisGetNoHeader("/area/elecFactor/AcChargingPile/"+areaIdStr, "0")
						if err == nil {
							//根据园区电损系数计算电量

							xi, err := strconv.ParseFloat(areaElecFactorStr, 64)
							if err == nil {
								areaElecFactorBtn = true
								if xi < 1 {
									xi = 1.02
								}
								utils.MyPrint(utils.PRINT_INFO, "桩号:", snNum, "获取了园区的电损系数:", xi, "计算之前的电量:", electricityKWH)
								electricityKWH = electricityKWH * xi
								utils.MyPrint(utils.PRINT_INFO, "桩号:", snNum, "获取了园区的电损系数:", xi, "计算之后的电量:", electricityKWH)
							}

						}
					}

				}
			}

		}

		//end
		if !areaElecFactorBtn {
			electricityKWH = processElectricity(electricityKWH)
			if err != nil {
				utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzePowerMessageNew,3:功率数据转换失败"))
			}
		}

		duration, err := AnalyzeDevDurationGet(snNum + "/openTime")
		if err != nil {
			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzePowerMessageNew,3:功率数据转换失败"))
		}
		openType, err := GetOpenType(snNum)
		if err != nil {
			utils.WrapError(err, "OutLetClose关闭设备:10，活动订单sn失败")
		}

		electricityLastStr, err := RedisGet(snNum+"/electricity", "0")
		if err != nil {
			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
		}
		electricityLast, err := strconv.ParseFloat(electricityLastStr, 64)
		if err != nil {
			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
		}
		utils.MyPrint(utils.PRINT_INFO, "桩号:", snNum, "getActualElectricity之前的电量:", electricityKWH, "上次电量：", electricityLast)
		electricityKWH = getActualElectricity(snNum, electricityKWH, electricityLast, duration)

		utils.MyPrint(utils.PRINT_INFO, "桩号:", snNum, "getActualElectricity之后的电量:", electricityKWH)

		isWebsocketMonitor, err := RedisGetNoHeader("/qld2websocket/"+snNum, "0")

		var amountFen = int64(0)

		if err != nil {
			utils.MyPrint(utils.PRINT_ERROR, err)
		} else {
			if isWebsocketMonitor == "1" {
				amountFen2, err := calculateAmount(snNum, electricityKWH, duration, openType)
				if err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzePowerMessageNew,3:功率数据转换失败"))
				}
				amountFen = amountFen2
				utils.MyPrint(utils.PRINT_WARN, electricityKWH, powerKW, voltageV, currentA, amountFen2)
				if err = MqttNoticeSend(snNum+"/amount", strconv.FormatInt(amountFen, 10)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
				}
			}
		}
		//amountFen, err := calculateAmount(snNum, electricityKWH, duration, openType)
		//if err != nil {
		//	utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzePowerMessageNew,3:功率数据转换失败"))
		//}
		//
		//utils.MyPrint(utils.PRINT_WARN, electricityKWH, powerKW, voltageV, currentA, amountFen)

		_ = RedisSave(snNum+"/electricity", strconv.FormatFloat(electricityKWH, 'E', -1, 64))
		if err = MqttNoticeSend(snNum+"/electricity", strconv.FormatFloat(electricityKWH, 'E', -1, 64)); err != nil {
			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
		}
		_ = RedisSave(snNum+"/power", strconv.FormatFloat(powerKW, 'E', -1, 64))
		if err = MqttNoticeSend(snNum+"/power", strconv.FormatFloat(powerKW, 'E', -1, 64)); err != nil {
			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
		}
		_ = RedisSave(snNum+"/voltage", strconv.FormatFloat(voltageV, 'E', -1, 64))
		if err = MqttNoticeSend(snNum+"/voltage", strconv.FormatFloat(voltageV, 'E', -1, 64)); err != nil {
			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
		}
		_ = RedisSave(snNum+"/current", strconv.FormatFloat(currentA, 'E', -1, 64))
		if err = MqttNoticeSend(snNum+"/current", strconv.FormatFloat(currentA, 'E', -1, 64)); err != nil {
			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
		}
		//将功率存储到redis的List中,只存储前10个_start
		err = SetPowerToRedis(powerKW*1000, snNum)
		if err != nil {
			fmt.Println("将功率存储到redis的List中失败了:", err)
		}
		//将功率存储到redis的List中,只存储前10个_end

		//amountLastStr, err := RedisGet(snNum+"/amount", "0")
		//if err != nil {
		//	utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
		//}
		//amountLast, err := strconv.ParseInt(amountLastStr, 10, 64)
		//if err != nil {
		//	utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,2:etcd服务电费数据转换失败"))
		//}
		//amountRecordLast, err := RedisGet(snNum+"/amountRecord", "")
		//if err != nil {
		//	utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
		//}
		//if err = RedisSave(snNum+"/amount", strconv.FormatInt(amountFen, 10)); err != nil {
		//	utils.MyPrint(utils.PRINT_ERROR, err.Error())
		//}
		//if err = MqttNoticeSend(snNum+"/amount", strconv.FormatInt(amountFen, 10)); err != nil {
		//	utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
		//}
		//amountRecord, err := CalculateAmountRecord(snNum)
		//if err != nil {
		//	utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "OutLetClose关闭设备:10，活动订单sn失败"))
		//	return
		//}
		//if err = RedisSave(snNum+"/amountRecord", amountRecord); err != nil {
		//	utils.MyPrint(utils.PRINT_ERROR, err.Error())
		//}
		//remainAmount, _ := calculateRemainAmount(snNum) // 必须在amount保存的后面
		//_ = RedisSave(snNum+"/remainAmount", strconv.FormatInt(remainAmount, 10))
		//if err = MqttNoticeSend(snNum+"/remainAmount", strconv.FormatInt(remainAmount, 10)); err != nil {
		//	utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:7,orderFinish信息推送失败"))
		//}

		// 余额不足，自动结算
		//if remainAmount < 0 {
		//	utils.MyPrint(utils.PRINT_WARN, "******************关闭设备******************")
		//	if timeout, _, err := OperateDevice(snNum, OperateDeviceCloseIOValue, 0, 2, 15); err != nil {
		//		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
		//	} else if timeout {
		//		utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "AnalyzePowerMessageType5,1:关闭应答超时"))
		//	} else {
		//		//1充满停止、2金额用完停止、3闲置停止、4汽车未允许充电停止、5拔出停止、6功率超限停止、7电量超限停止、8时间超限停止
		//		powerFinishOrder(snNum, 2, amountLast, duration, electricityKWH, amountRecordLast)
		//		return
		//	}
		//}
		//var amountRecord string
		//amountRecord = ""
		socketScooterThreshold := 10.0
		devType, err := getDevType(snNum)
		if err == nil {
			//获取电量判断的阈值
			if devType == 5 {
				socketThresholdRedis, err := RedisGetNoHeader("/socket/threshold", "10")
				if err == nil {
					socketFloatValue, err := strconv.ParseFloat(socketThresholdRedis, 64)
					if err == nil {
						socketScooterThreshold = socketFloatValue
					}

				}
			}

			if devType == 9 {
				scooterThresholdRedis, err := RedisGetNoHeader("/scooter/threshold", "50")
				if err == nil {
					scooterFloatValue, err := strconv.ParseFloat(scooterThresholdRedis, 64)
					if err == nil {
						socketScooterThreshold = scooterFloatValue
					}

				}
			}
			utils.MyPrint(utils.PRINT_INFO, snNum, "获取的电量判断阈值:", socketScooterThreshold, "设备类型:", devType)
		} else {
			utils.MyPrint(utils.PRINT_ERROR, snNum, "获取设备类型失败")
		}

		//zhangsen modify 20210526   增加最大充电时长
		if timetype, err1 := RedisGet(snNum+"/timeType", "0"); err1 != nil {
			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err1, "timetype:获取充满判断类型失败"))
		} else if timetype == "1" {
			if hournum, err2 := RedisGet(snNum+"/hourNum", "0"); err2 != nil {
				utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err1, "hournum:获取最大充满时长失败"))
			} else {
				hour, err3 := strconv.Atoi(hournum)
				//	utils.MyPrint(utils.PRINT_ERROR, "测试代码打印")
				//	fmt.Printf("hahahahah hour %d timetype %s\n", hour, timetype)
				if err3 != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err3, "hournum:转化为整形变量失败"))
				} else {
					if duration > int64(hour*3600) {
						if timeout, operateFlag, err := OperateDevice(snNum, OperateDeviceCloseIOValue, 0, 2, 15); err != nil {
							utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzePowerMessageType1,1:redis数据保存失败"))
						} else if timeout {
							utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "AnalyzePowerMessageType1,1:设备控制超时"))
						} else if operateFlag != 0 {
							utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "AnalyzePowerMessageType1,1:设备控制失败"))
						} else {
							if electricityKWH > socketScooterThreshold {
								utils.MyPrint(utils.PRINT_ERROR, snNum, "电量错误")
								electricityKWH = 0.5
							}

							amountFen, err := calculateAmount(snNum, electricityKWH, duration, openType)
							if err != nil {
								utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzePowerMessageNew,3:功率数据转换失败"))
							}
							amountRecord, err := CalculateAmountRecord(snNum)
							if err != nil {
								utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "CalculateAmountRecord,err "))
							}
							//1充满停止、2金额用完停止、3闲置停止、4汽车未允许充电停止、5拔出停止、6功率超限停止、7电量超限停止、8时间超限停止
							powerFinishOrder(snNum, 8, amountFen, duration, electricityKWH, amountRecord)
							return
						}
					}
				}
			}
		}

		var qldOutletControlJson models.QldOutletControlJson
		if qldOutletControlJsonStr, err1 := RedisGet(snNum+"/control", "{}"); err1 != nil {
			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err1, "calculateAmount:3，获取设备etcd价格失败"))
		} else if err := json.Unmarshal([]byte(qldOutletControlJsonStr), &qldOutletControlJson); err != nil {
			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err1, "calculateAmount:3，获取设备etcd价格失败"))
		} else {
			if electricityKWH > electricityLast && electricityKWH >= qldOutletControlJson.PushOverPriceModeElectricity && electricityLast < qldOutletControlJson.PushOverPriceModeElectricity {
				fmt.Println(",,,,,,,,,,,,,,,,,,,,,,,,,,,,,", electricityKWH, electricityLast)
				if userIdStr, err7 := RedisGet(snNum+"/userId", "0"); err7 != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err7, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
				} else if userId, err8 := strconv.ParseInt(userIdStr, 10, 64); err8 != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err8, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
				} else {
					//fmt.Println(",,,,,,,,,,,,,,,,,,,,,,,,,,,,,")
					ElectriciyWeiXinMassage(userId, "电量超过"+strconv.FormatFloat(qldOutletControlJson.PushOverPriceModeElectricity, 'E', -1, 64)+"度电，将按电量计费。", "电量超限", snNum)
					ElectriciyWeiXinMassageGdt(userId, "电量超过"+strconv.FormatFloat(qldOutletControlJson.PushOverPriceModeElectricity, 'E', -1, 64)+"度电，将按电量计费。", "电量超限", snNum)
					ElectriciyAliMassageGdt(userId, "电量超过"+strconv.FormatFloat(qldOutletControlJson.PushOverPriceModeElectricity, 'E', -1, 64)+"度电，将按电量计费。", "电量超限", snNum)
				}
			} else {
				//	fmt.Println("]]]]]]]]]]]]]]]]]]]]]]]]]]]]]", electricityKWH, electricityLast)
			}

			if openType != 1 { // 小交流在打开模式为1的情况下不断电
				//若功率未达到充满标准，更新时间
				if powerKW > qldOutletControlJson.ChargeFullLowPower {
					if err = RedisSave(snNum+"/powerPowerStartLowTime", time.Now().Format("2006-01-02 15:04:05")); err != nil {
						utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
					}
					if err = RedisSave(snNum+"/powerPowerStartLowTimeSecond", time.Now().Format("2006-01-02 15:04:05")); err != nil {
						utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTimeSecond,1:etcd服务数据保存失败"))
					}
					utils.MyPrint(utils.PRINT_WARN, powerKW, ">", qldOutletControlJson.ChargeFullLowPower)
				} else {

					utils.MyPrint(utils.PRINT_INFO, "桩号:", snNum, "qldOutletControlJson.ChargeFullLowPowerSecond:", qldOutletControlJson.ChargeFullLowPowerSecond, "qldOutletControlJson.ChargeFullKeepDurationSecond:", qldOutletControlJson.ChargeFullKeepDurationSecond)
					//第二个控制策略_start
					utils.MyPrint(utils.PRINT_INFO, "第二个控制策略判断:", "qldOutletControlJson.ChargeFullLowPower:", qldOutletControlJson.ChargeFullLowPower, "qldOutletControlJson.ChargeFullLowPowerSecond:", qldOutletControlJson.ChargeFullLowPowerSecond, "powerKW:", powerKW)
					if qldOutletControlJson.ChargeFullLowPower > qldOutletControlJson.ChargeFullLowPowerSecond {
						if powerKW > qldOutletControlJson.ChargeFullLowPowerSecond {
							if err = RedisSave(snNum+"/powerPowerStartLowTimeSecond", time.Now().Format("2006-01-02 15:04:05")); err != nil {
								utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
							}
						}
					}

					//第二个控制策略_end

					//记录功率第三次达到充满标准后的时间,防止第一,二次为误报,价格策略计算浮充开始时间以第三次为准_start

					//将功率存储到redis的List中,只存储前3个,先从redis里面获取功率list 判断是否小于3个数字
					LowpowerList, err := RedisGetNoHeaderList("/qld2devservice/" + snNum + "/listLowFullPower")

					if err == nil {
						utils.MyPrint(utils.PRINT_INFO, "LowpowerList长度:", len(LowpowerList))
						if len(LowpowerList) < 3 {
							//	将功率存到redis中
							if err := RedisSaveNoHeaderList("/qld2devservice/"+snNum+"/listLowFullPower", strconv.FormatFloat(power, 'f', 6, 64)); err == nil {

								if len(LowpowerList) >= 1 {
									utils.MyPrint(utils.PRINT_INFO, "桩号:", snNum, "记录浮充时间:", time.Now().Format("2006-01-02 15:04:05"), "len(LowpowerList):", len(LowpowerList))
									RedisSaveExpirationNoHeader("/qld2devservice/"+snNum+"/startLowFullTime", time.Now().Format("2006-01-02 15:04:05"), qldOutletControlJson.ChargeFullKeepDuration+300)
								}

								utils.MyPrint(utils.PRINT_INFO, "桩号:", snNum, "len(LowpowerList):", len(LowpowerList))
							}
						}
					}

					//记录功率第三次达到充满标准后的时间,防止第一,二次为误报,价格策略计算浮充开始时间以第三次为准_end

					utils.MyPrint(utils.PRINT_WARN, powerKW, "<=", qldOutletControlJson.ChargeFullLowPower)
				}
				// 读取开始充满低功率的时长，以根据功率判断是否充满电
				powerPowerStartLowTimeDuration, err := AnalyzeDevDurationGet(snNum + "/powerPowerStartLowTime")
				if err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerDurationGet,2:etcd服务设备打开时间数据转换失败"))
				}

				// 读取开始充满低功率的时长，以根据功率判断是否充满电
				powerPowerStartLowTimeDurationSecond, err := AnalyzeDevDurationGet(snNum + "/powerPowerStartLowTimeSecond")
				if err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerDurationGet,2:etcd服务设备打开时间数据转换失败"))
				}

				utils.MyPrint(utils.PRINT_INFO, "桩号:", snNum, "powerPowerStartLowTimeDuration:", powerPowerStartLowTimeDuration, "qldOutletControlJson.ChargeFullKeepDuration:", qldOutletControlJson.ChargeFullKeepDuration)
				utils.MyPrint(utils.PRINT_INFO, "桩号:", snNum, "powerPowerStartLowTimeDurationSecond:", powerPowerStartLowTimeDurationSecond, "qldOutletControlJson.ChargeFullKeepDurationSecond:", qldOutletControlJson.ChargeFullKeepDurationSecond)
				// 充满低功率持续，认为充满
				chargeFullBtn := false
				if powerPowerStartLowTimeDurationSecond > qldOutletControlJson.ChargeFullKeepDurationSecond && qldOutletControlJson.ChargeFullKeepDurationSecond > 0 && qldOutletControlJson.ChargeFullLowPowerSecond > 0 && qldOutletControlJson.ChargeFullLowPower > qldOutletControlJson.ChargeFullLowPowerSecond {
					chargeFullBtn = true
				}
				//if powerPowerStartLowTimeDuration > qldOutletControlJson.ChargeFullKeepDuration { // 2分钟充满  before
				if (powerPowerStartLowTimeDuration > qldOutletControlJson.ChargeFullKeepDuration) || chargeFullBtn { // 2分钟充满
					if err = RedisSave(snNum+"/powerPowerStartLowTime", time.Now().Format("2006-01-02 15:04:05")); err != nil {
						utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
					} else {
						utils.MyPrint(utils.PRINT_WARN, "******************关闭设备******************")
						if timeout, _, err := OperateDevice(snNum, OperateDeviceCloseIOValue, 0, 2, 15); err != nil {
							utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
						} else if timeout {
							utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "AnalyzePowerMessageType5,1:关闭应答超时"))
						} else {
							if err = RedisSave(snNum+"/powerPowerStartLowTime", time.Now().Format("2006-01-02 15:04:05")); err != nil {
								utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
							} else {
								if powerKW < 0.001 {
									if electricityKWH > socketScooterThreshold {
										utils.MyPrint(utils.PRINT_ERROR, snNum, "电量错误")
										electricityKWH = 0.5
									}

									amountFen, err := calculateAmount(snNum, electricityKWH, duration, openType)
									if err != nil {
										utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzePowerMessageNew,3:功率数据转换失败"))
									}
									amountRecord, err := CalculateAmountRecord(snNum)
									if err != nil {
										utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "CalculateAmountRecord,err "))
									}
									//1充满停止、2金额用完停止、3闲置停止、4汽车未允许充电停止、5拔出停止、6功率超限停止、7电量超限停止、8时间超限停止
									powerFinishOrder(snNum, 3, amountFen, duration, electricityKWH, amountRecord)
								} else {
									if electricityKWH > socketScooterThreshold {
										utils.MyPrint(utils.PRINT_ERROR, snNum, "电量错误")
										electricityKWH = 0.5
									}

									amountFen, err := calculateAmount(snNum, electricityKWH, duration, openType)
									if err != nil {
										utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzePowerMessageNew,3:功率数据转换失败"))
									}
									amountRecord, err := CalculateAmountRecord(snNum)
									if err != nil {
										utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "CalculateAmountRecord,err "))
									}
									powerFinishOrder(snNum, 1, amountFen, duration, electricityKWH, amountRecord)
								}
								return
							}
						}
					}
				}
			} else {
				str := fmt.Sprintf("%s 这里是opentype 等于1的判断逻辑\n", snNum)
				utils.MyPrint(utils.PRINT_ERROR, str)
				// 余额不足，通知
				//if remainAmount < qldOutletControlJson.BalanceShort {
				//	if remainAmountShortNoticeTimeStr, err2222 := RedisGet(snNum+"/remainAmountShortNoticeTime", ""); err2222 != nil {
				//		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err2222, "SaveOpenTime,1:etcd服务数据保存失败"))
				//	} else if len(remainAmountShortNoticeTimeStr) == 0 {
				//		//通知余额不足
				//		if userIdStr, err222 := RedisGet(snNum+"/userId", "0"); err222 != nil {
				//			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err222, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
				//		} else if userId, err1111 := strconv.ParseInt(userIdStr, 10, 64); err1111 != nil {
				//			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err1111, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
				//		} else {
				//			BalanceWeiXinMassage(userId, remainAmount, "余额不足"+strconv.FormatFloat(float64(qldOutletControlJson.BalanceShort)/100, 'E', -1, 64)+"元，请及时充值。")
				//		}
				//
				//		if err111 := RedisSave(snNum+"/remainAmountShortNoticeTime", time.Now().Format("2006-01-02 15:04:05")); err111 != nil {
				//			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err111, "SaveOpenTime,1:etcd服务数据保存失败"))
				//		}
				//	} else if remainAmountShortNoticeTime, err56 := time.Parse("2006-01-02 15:04:05", remainAmountShortNoticeTimeStr); err56 != nil {
				//		errNew := utils.WrapError(err56, "AnalyzeDevPowerDurationGet,2:etcd服务设备打开时间数据转换失败")
				//		utils.MyPrint(utils.PRINT_ERROR, errNew.Msg())
				//	} else if time.Now().Sub(remainAmountShortNoticeTime) > (time.Second * time.Duration(qldOutletControlJson.PushBalanceShortDuration)) {
				//		//通知余额不足20元
				//		if userIdStr, err15 := RedisGet(snNum+"/userId", "0"); err15 != nil {
				//			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err15, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
				//		} else if userId, err1 := strconv.ParseInt(userIdStr, 10, 64); err1 != nil {
				//			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err1, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
				//		} else {
				//			BalanceWeiXinMassage(userId, remainAmount, "余额不足"+strconv.FormatFloat(float64(qldOutletControlJson.BalanceShort)/100, 'E', -1, 64)+"元，请及时充值。")
				//		}
				//
				//		if err11 := RedisSave(snNum+"/remainAmountShortNoticeTime", time.Now().Format("2006-01-02 15:04:05")); err11 != nil {
				//			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err11, "SaveOpenTime,1:etcd服务数据保存失败"))
				//		}
				//	}
				//}
			}
			// 功率超限，自动结算
			if qldOutletControlJson.MaxPower > 0 {
				if powerLastStr, err := RedisGet(snNum+"/powerLast", "0"); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
				} else if powerLast, err := strconv.ParseFloat(powerLastStr, 64); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败"))
				} else if powerKW > qldOutletControlJson.MaxPower && powerLast > qldOutletControlJson.MaxPower {
					utils.MyPrint(utils.PRINT_WARN, "******************关闭设备******************")
					if timeout, _, err := OperateDevice(snNum, OperateDeviceCloseIOValue, 0, 2, 15); err != nil {
						utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
					} else if timeout {
						utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "SaveOpenTime,1:etcd服务数据保存失败"))
					} else {
						if electricityKWH > socketScooterThreshold {
							utils.MyPrint(utils.PRINT_ERROR, snNum, "电量错误")
							electricityKWH = 0.5
						}

						amountFen, err := calculateAmount(snNum, electricityKWH, duration, openType)
						if err != nil {
							utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzePowerMessageNew,3:功率数据转换失败"))
						}
						amountRecord, err := CalculateAmountRecord(snNum)
						if err != nil {
							utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "CalculateAmountRecord,err "))
						}
						//1充满停止、2金额用完停止、3闲置停止、4汽车未允许充电停止、5拔出停止、6功率超限停止、7电量超限停止、8时间超限停止
						powerFinishOrder(snNum, 6, amountFen, duration, electricityKWH, amountRecord)
						return
					}
				}
				if err = RedisSave(snNum+"/powerLast", strconv.FormatFloat(powerKW, 'E', -1, 64)); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, err.Error())
				}
			}
			// 电量超限，自动结算
			if qldOutletControlJson.MaxElectricity > 0 && electricityKWH > qldOutletControlJson.MaxElectricity {
				utils.MyPrint(utils.PRINT_WARN, "******************关闭设备******************")
				if timeout, _, err := OperateDevice(snNum, OperateDeviceCloseIOValue, 0, 2, 15); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
				} else if timeout {
					utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "SaveOpenTime,1:etcd服务数据保存失败"))
				} else {
					if electricityKWH > socketScooterThreshold {
						utils.MyPrint(utils.PRINT_ERROR, snNum, "电量错误")
						electricityKWH = 0.5
					}

					amountFen, err := calculateAmount(snNum, electricityKWH, duration, openType)
					if err != nil {
						utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzePowerMessageNew,3:功率数据转换失败"))
					}
					amountRecord, err := CalculateAmountRecord(snNum)
					if err != nil {
						utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "CalculateAmountRecord,err "))
					}
					//1充满停止、2金额用完停止、3闲置停止、4汽车未允许充电停止、5拔出停止、6功率超限停止、7电量超限停止、8时间超限停止
					powerFinishOrder(snNum, 7, amountFen, duration, electricityKWH, amountRecord)
					return
				}
			}
			// 时间超限，自动结算
			if int64(qldOutletControlJson.MaxDuration) > 0 && duration > int64(qldOutletControlJson.MaxDuration) {
				utils.MyPrint(utils.PRINT_WARN, "******************关闭设备******************")
				if timeout, _, err := OperateDevice(snNum, OperateDeviceCloseIOValue, 0, 2, 15); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "SaveOpenTime,1:etcd服务数据保存失败"))
				} else if timeout {
					utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "SaveOpenTime,1:etcd服务数据保存失败"))
				} else {
					if electricityKWH > socketScooterThreshold {
						utils.MyPrint(utils.PRINT_ERROR, snNum, "电量错误")
						electricityKWH = 0.5
					}
					amountFen, err := calculateAmount(snNum, electricityKWH, duration, openType)
					if err != nil {
						utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzePowerMessageNew,3:功率数据转换失败"))
					}
					amountRecord, err := CalculateAmountRecord(snNum)
					if err != nil {
						utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "CalculateAmountRecord,err "))
					}
					//1充满停止、2金额用完停止、3闲置停止、4汽车未允许充电停止、5拔出停止、6功率超限停止、7电量超限停止、8时间超限停止
					powerFinishOrder(snNum, 8, amountFen, duration, electricityKWH, amountRecord)
					return
				}
			}
		}
	} else {
		response = "{\"data\":\"" + isWorking + "\"}"
	}
	return
}

func AnalyzeDevPowerElectricityGet(snNum string) (electricity float64, err error) {
	electricityStr, err := RedisGet(snNum+"/electricity", "0")
	if err != nil {
		errNew := utils.WrapError(err, "AnalyzeDevPowerElectricityGet,1:etcd服务电量数据获取失败")
		return 0, errNew
	}
	if electricityStr == "" {
		return 0, nil
	}
	electricity1, err := strconv.ParseFloat(electricityStr, 64)
	if err != nil {
		errNew := utils.WrapError(err, "AnalyzeDevPowerElectricityGet,2:etcd服务电量数据转换失败")

		utils.MyPrint(utils.PRINT_ERROR, errNew.Msg())
		return 0, errNew
	}
	timetype, err := RedisGet(snNum+"/timeType", "0")
	if err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "stateFinishOrder:10，timeType获取失败"))
	}
	if timetype == "2" {
		stepelec, _ := RedisGet(snNum+"/stepelec", "0")

		if stepelec != "0" {
			stepfloat, _ := strconv.ParseFloat(stepelec, 64)
			electricity1 += stepfloat
		}

	}
	return electricity1, nil
}

func AnalyzeDevPowerAmountGet(snNum string) (amount int64, err error) {
	amount, _, err = CalculateAmountType(snNum)
	if err != nil {
		errNew := utils.WrapError(err, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败")
		return 0, errNew
	}
	//amountStr, err := RedisGet(snNum+"/amount", "0")
	//if err != nil {
	//	errNew := utils.WrapError(err, "AnalyzeDevPowerAmountGet,1:etcd服务电费数据获取失败")
	//	return 0, errNew
	//}
	//if amountStr == "" {
	//	return 0, nil
	//}
	//
	//
	//amount, err = strconv.ParseInt(amountStr, 10, 64)
	//if err != nil {
	//	errNew := utils.WrapError(err, "AnalyzeDevPowerAmountGet,2:etcd服务电费数据转换失败")
	//
	//	utils.MyPrint(utils.PRINT_ERROR, errNew.Msg())
	//	return 0, errNew
	//}
	return amount, nil
}

func SaveOpenTime(snNum string) (err error) {
	timeNowStr := time.Now().Format("2006-01-02 15:04:05")
	if err = RedisSave(snNum+"/openTime", timeNowStr); err != nil {
		errNew := utils.WrapError(err, "SaveOpenTime,1:etcd服务openTime数据保存失败")
		return errNew
	}
	if err = RedisSave(snNum+"/powerPowerStartLowTime", timeNowStr); err != nil {
		errNew := utils.WrapError(err, "SaveOpenTime,2:etcd服务powerPowerStartLowTime数据保存失败")
		return errNew
	}
	if err = RedisSave(snNum+"/powerCurrentStartLowTime", timeNowStr); err != nil {
		errNew := utils.WrapError(err, "SaveOpenTime,3:etcd服务powerCurrentStartLowTime数据保存失败")
		return errNew
	}
	if err = RedisSave(snNum+"/powerSocStartLowTime", timeNowStr); err != nil {
		errNew := utils.WrapError(err, "SaveOpenTime,4:etcd服务powerSocStartLowTime数据保存失败")
		return errNew
	}
	return nil
}
func AnalyzeDevDurationGet(key string) (duration int64, err error) {
	devTimeStr, err := RedisGet(key, time.Now().Format("2006-01-02 15:04:05"))
	if err != nil {
		errNew := utils.WrapError(err, "AnalyzeDevPowerDurationGet,1:etcd服务设备打开时间数据获取失败")
		return 0, errNew
	}
	devTime, err := time.Parse("2006-01-02 15:04:05", devTimeStr)
	if err != nil {
		errNew := utils.WrapError(err, "AnalyzeDevPowerDurationGet,2:etcd服务设备打开时间数据转换失败")

		utils.MyPrint(utils.PRINT_ERROR, errNew.Msg())
		return 0, errNew
	}
	return time.Now().Unix() - devTime.Unix(), nil
}

func SaveOpenType(snNum string, openType int64) (err error) {
	err = RedisSave(snNum+"/openType", strconv.FormatInt(openType, 10))

	if err != nil {
		errNew := utils.WrapError(err, "SaveOpenType,1:etcd服务数据保存失败")
		return errNew
	}
	return nil
}

func GetOpenType(snNum string) (openType int64, err error) {
	openTypeStr, err := RedisGet(snNum+"/openType", "0")

	utils.MyPrint(utils.PRINT_WARN, openTypeStr)
	if err != nil {
		errNew := utils.WrapError(err, "GetOpenType,1:etcd服务设备打开类型数据获取失败")
		return 0, errNew
	}
	openType, err = strconv.ParseInt(openTypeStr, 10, 64)
	if err != nil {
		errNew := utils.WrapError(err, "GetOpenType,2:etcd服务设备打开类型数据转换失败")

		utils.MyPrint(utils.PRINT_ERROR, errNew.Msg())
		return 0, errNew
	}
	return openType, nil
}

func GetUserBalance(userId int64) (balance int64, err error) {
	balanceStr, err := RedisGet("userBalance/"+strconv.FormatInt(userId, 10), "0")
	if err != nil {
		errNew := utils.WrapError(err, "GetUserBalance,1:etcd服务数据获取失败")
		return 0, errNew
	}
	balance, err = strconv.ParseInt(balanceStr, 10, 64)
	if err != nil {
		errNew := utils.WrapError(err, "GetUserBalance,2:etcd服务数据转换失败")

		utils.MyPrint(utils.PRINT_ERROR, errNew.Msg())
		return 0, errNew
	}
	return balance, nil
}

func ResetSoc(snNum, userIdStr, orderSn string) (err error) {
	response, err := SetUserDataEnd(GetOutletCurrentIn(snNum), userIdStr, orderSn, 30)

	utils.MyPrint(utils.PRINT_WARN, response)
	return
}

func getActualElectricity(snNum string, electricity, electricityLast float64, duration int64) (actualElectricity float64) {
	if electricityOpenStr, err := RedisGet(snNum+"/electricityOpen", "electricityOpen"); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet:redis服务electricityOpen数据获取失败"))
	} else if electricityOpenStr == "electricityOpen" {
		if electricity > 0 {
			if err = RedisSave(snNum+"/electricityOpen", strconv.FormatFloat(electricity, 'E', -1, 64)); err != nil {
				utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet:redis服务electricityOpen数据保存失败"))
			}
		}
		electricity = 0
	} else if electricityOpen, err := strconv.ParseFloat(electricityOpenStr, 64); err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet:redis服务electricityOpen数据解析失败"))
	} else {
		electricity1 := electricity - electricityOpen
		if electricity1 < 0 {
			electricity1 = 0
		}
		if (electricity1+0.0001) <= electricityLast || ((electricity1+1) > electricityLast && duration < 120) {
			//如何防毛刺
			utils.MyPrint(utils.PRINT_DEBUG, electricity, electricityLast, duration)
			electricity2 := electricity - electricityLast
			if electricity2 < 0 {
				electricity2 = 0
			}
			//if err = RedisSave(snNum+"/electricityOpen", strconv.FormatFloat(electricity-electricityLast, 'E', -1, 64)); err != nil {
			if err = RedisSave(snNum+"/electricityOpen", strconv.FormatFloat(electricity2, 'E', -1, 64)); err != nil {
				utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "AnalyzeDevPowerAmountGet:redis服务electricityOpen数据保存失败"))
			}
			electricity1 = electricityLast
		}
		utils.MyPrint(utils.PRINT_DEBUG, "electricity1:", electricity1)
		return math.Abs(electricity1)
	}
	return math.Abs(electricity)
}

func JudgeRestartDev(snNum string, power, electricity, current float64) (int64, error) {
	var ret int64
	ret = 0
	qldOutletControlJsonStr, err := RedisGet(snNum+"/control", "{}")
	if err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "获取控制策略失败"))
	}
	var control models.QldOutletControlJson
	err = json.Unmarshal([]byte(qldOutletControlJsonStr), &control)
	if err != nil {
		utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "控制策略解析失败"))
	}

	stepelec, _ := RedisGet(snNum+"/stepelec", "0")
	if err != nil {
		errNew := utils.WrapError(err, "上次的电量获取失败")
		utils.MyPrint(utils.PRINT_ERROR, errNew.Msg())
		return ret, err
	}
	//	fmt.Printf("上次终止充电保存的电量%s\n", stepelec)
	if stepelec != "0" {
		stepfloat, err := strconv.ParseFloat(stepelec, 64)
		if err != nil {
			utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "旧电量转换失败"))
		} else {
			electricity += stepfloat
		}
	}
	fmt.Printf("control.MaxPower %f current %f 功率 %f \n", control.MaxPower, current, power)
	if current > 0 { //当前在充电
		if power > control.MaxPower { // 检查是否需要停止设备充电
			// duration, err := RedisGet(snNum+"/duration", "")
			// if err != nil {
			// 	errNew := utils.WrapError(err, "充电时长获取失败")
			// 	utils.MyPrint(utils.PRINT_ERROR, errNew.Msg())
			// 	return err
			// }
			// restart, err := RedisGet(snNum+"/restart", "")
			// if err != nil {
			// 	errNew := utils.WrapError(err, "重新开始充电时间")
			// 	utils.MyPrint(utils.PRINT_ERROR, errNew.Msg())
			// 	return err
			// }
			//if restart == "" || restart == "0" {
			restart, err := RedisGet(snNum+"/openTime", "")
			if err != nil {
				errNew := utils.WrapError(err, "充电开始时间")
				utils.MyPrint(utils.PRINT_ERROR, errNew.Msg())
				return ret, err
			}
			//	}
			timeLayout := "2006-01-02 15:04:05"
			restarttime, err := time.ParseInLocation(timeLayout, restart, time.Local)
			now := time.Now()
			now = now.Add(time.Minute * 5)
			diff := now.Sub(restarttime)

			fmt.Println(restarttime)
			fmt.Println(now)
			fmt.Println(diff)

			kwh := (diff.Hours()) * control.MaxPower // 计算得出应该停止的充电电量
			//		fmt.Printf("计算得出应该停止的充电电量 %f,当前电量%f\n", kwh, electricity)
			if electricity > kwh { //按照现行的功率估算，充电电量已经越限  停止充电5分钟
				//			fmt.Printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n")
				//			fmt.Printf("中途停止充电！！！！！！！！！！！！！！\n")
				if timeout, _, err := OperateDevice(snNum, OperateDeviceCloseIOValue, 0, 2, 15); err != nil {
					utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "设备操作失败，中途停止设备失败"))
				} else if timeout { //操作超时
					utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "设备操作失败，超时控制"))
				} else { //停止设备成功
					now = time.Now()
					timeLayout := "2006-01-02 15:04:05"
					strtime := now.Format(timeLayout)
					if err = RedisSave(snNum+"/stoptime", strtime); err != nil {
						utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "中途停止设备出错"))
					}
					ret = 1
					// diff2 := now.Sub(restarttime)
					// duration1 := int64(diff2.Seconds())
					// duration2, _ := strconv.ParseInt(duration, 10, 64)
					// duration1 += duration2
					// fmt.Printf("额外的充电时间%d\n", duration1)
					// if err = RedisSave(snNum+"/duration", strconv.FormatInt(duration1, 10)); err != nil {
					// 	utils.MyPrint(utils.PRINT_ERROR, "额外充电时间保存失败")
					// }
					//			fmt.Printf("额外的电量 %f\n", electricity)
					if err = RedisSave(snNum+"/stepelec", strconv.FormatFloat(electricity, 'f', 5, 64)); err != nil {
						utils.MyPrint(utils.PRINT_ERROR, "电量保存失败")
					}
					time.AfterFunc(10*time.Minute, func() {
						isWorking, _ := RedisGet(snNum+"/isWorking", "0")
						if isWorking == "0" {
							return
						}
						//				fmt.Printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n")
						//				fmt.Printf("中途开始充电！！！！！！！！！！！！！！\n")
						if timeout, _, err := OperateDevice(snNum, OperateDeviceOpenIOValue, 0, 2, 15); err != nil {
							utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "设备操作失败，中途打开设备失败"))
						} else if timeout { //操作超时
							utils.MyPrint(utils.PRINT_ERROR, utils.NewError(utils.ErrorTypeStop, "设备操作失败，超时控制"))
						} else {
							now = time.Now()
							timeLayout := "2006-01-02 15:04:05"
							strtime := now.Format(timeLayout)
							if err = RedisSave(snNum+"/restart", strtime); err != nil {
								utils.MyPrint(utils.PRINT_ERROR, utils.WrapError(err, "中途开始时间保存出错"))
							}
						}
					})

				}
			}
		}
	}
	return ret, nil
}
